您的位置:首页 > 其它

二叉树的建立和基本操作

2014-11-17 11:29 597 查看
二叉树的建立和基本操作

递归实现:

#include <iostream>
using namespace std;

typedef int TelemType;
typedef struct BinaryTreeNode    //二叉树的结构体
{
    TelemType data;
    struct BinaryTreeNode *Left;
    struct BinaryTreeNode *Right;
}Node,*BiTree;

//创建二叉树,顺序依次为中间节点->左子树->右子树
void CreateBinaryTree(BiTree &T)
{
    TelemType ch;
    cin>>ch;
    if(ch == 0)     //如果是叶子节点,接下来的左、右子树分别赋值为0
        T = NULL;
    else
    {
        T = (Node*)malloc(sizeof(Node));
        T->data = ch;
        CreateBinaryTree(T->Left);  //递归创建左子树
        CreateBinaryTree(T->Right);  //递归创建右子树
    }
}

//先序遍历(根节点,左节点,右节点)
void preOrderTraverse(BiTree root)
{
    if(root)
    {
        cout<<root->data<<' ';
        preOrderTraverse(root->Left);
        preOrderTraverse(root->Right);
    }
}

//中序遍历(左节点,根节点,右节点)
void inOrderTraverse(BiTree root)
{
    if(root)
    {
        inOrderTraverse(root->Left);
        cout<<root->data<<' ';
        inOrderTraverse(root->Right);
    }
}

//后序遍历(左节点,右节点,根节点,)
void lastOrderTraverse(BiTree root)
{
    if(root)
    {
        lastOrderTraverse(root->Left);
        lastOrderTraverse(root->Right);
        cout<<root->data<<' ';
    }
}

//二叉树节点总数目
int Nodenum(BiTree root)
{
    if(root == NULL)
        return 0;
    else
        return 1+Nodenum(root->Left)+Nodenum(root->Right); //加上根节点
}

//二叉树的深度
int DepthOfTree(BiTree root)
{
    if(root == NULL)
        return 0;
    else
        return DepthOfTree(root->Left)>DepthOfTree(root->Right)?DepthOfTree(root->Left)+1:DepthOfTree(root->Right)+1;
}

//二叉树叶子节点数
int Leafnum(BiTree root)
{
    if(root == NULL)
        return 0;
    else if((root->Left == NULL)&&(root->Right == NULL))
        return 1;
    else
        return (Leafnum(root->Left)+Leafnum(root->Right);
}

int main()
{
    BiTree root;
    CreateBinaryTree(root);
    
    cout<<"二叉树建立成功"<<endl;
    cout<<"二叉树总节点数为:"<<Nodenum(root)<<endl;
    cout<<"二叉树深度为:"<<DepthOfTree(root)<<endl;
    cout<<"二叉树叶子节点数为:"<<Leafnum(root)<<endl;

    cout<<"前序遍历结果:"<<endl;
    preOrderTraverse(root);
    cout<<endl;

    cout<<"中序遍历结果:"<<endl;
    inOrderTraverse(root);
    cout<<endl;

    cout<<"后序遍历结果:"<<endl;
    lastOrderTraverse(root);
    cout<<endl;
    return 0;
}


分别输入两个二叉树来验证结果:

第一个二叉树为:







第二个二叉树为:








非递归实现:

#include<iostream>
#include<queue>
#include<stack>
using namespace std;

typedef int TelemType;
typedef struct BiTNode
{
    TelemType data;
    struct BiTNode *lchild, *rchild;
}BiTNode,*BiTree;

//创建二叉树,顺序依次为中间节点->左子树->右子树
void CreateBiTree(BiTree &T)
{
    TelemType ch;
    cin>>ch;
    if(ch == 0)     //如果是叶子节点,接下来的左、右子树分别赋值为0
        T = NULL;
    else
    {
        T = (BiTNode*)malloc(sizeof(BiTNode));
        T->data = ch;
        CreateBiTree(T->lchild);  //递归创建左子树
        CreateBiTree(T->rchild);  //递归创建右子树
    }
}

void PreOrder_Nonrecursive(BiTree T)     //先序遍历的非递归
{
    if(!T)  return ;
    stack<BiTree> s;
    while(T)          // 左子树上的节点全部压入到栈中
    {
        s.push(T);
        cout<<T->data<<" ";
        T = T->lchild;
    }
    while(!s.empty())
    {
        BiTree temp = s.top()->rchild;  // 栈顶元素的右子树
        s.pop();                        // 弹出栈顶元素
        while(temp)          // 栈顶元素存在右子树,则对右子树同样遍历到最下方
        {
            cout<<temp->data<<" ";
            s.push(temp);
            temp = temp->lchild;
        }
    }
}

void InOrderTraverse(BiTree T)   // 中序遍历的非递归
{
    if(!T)   return ;
    stack<BiTree> S;
    BiTree curr = T->lchild;    // 指向当前要检查的节点
    S.push(T);
    while(curr != NULL || !S.empty())
    {
        while(curr != NULL)    // 一直向左走
        {
            S.push(curr);
            curr = curr->lchild;
        }
        curr = S.top();
        S.pop();
        cout<<curr->data<<" ";
        curr = curr->rchild;
    }
}

void PostOrder_Nonrecursive(BiTree T)  // 后序遍历的非递归
{
    stack<BiTree> S;
    BiTree curr = T ;           // 指向当前要检查的节点
    BiTree previsited = NULL;    // 指向前一个被访问的节点
    while(curr != NULL || !S.empty())  // 栈空时结束
    {
        while(curr != NULL)            // 一直向左走直到为空
        {
            S.push(curr);
            curr = curr->lchild;
        }
        curr = S.top();     // 当前节点的右孩子如果为空或者已经被访问,则访问当前节点
        if(curr->rchild == NULL || curr->rchild == previsited)
        {
            cout<<curr->data<<" ";
            previsited = curr;
            S.pop();
            curr = NULL;
        }
        else
            curr = curr->rchild;      // 否则访问右孩子
    }
}

int visit(BiTree T)
{
    if(T)
    {
        printf("%d ",T->data);
        return 1;
    }
    else  return 0;
}
void LeverTraverse(BiTree T)   //非递归层次遍历二叉树
{
    queue <BiTree> Q;
    BiTree p;
    p = T;
    if(visit(p)==1)
        Q.push(p);
    while(!Q.empty())
    {
        p = Q.front();
        Q.pop();
        if(visit(p->lchild) == 1)
            Q.push(p->lchild);
        if(visit(p->rchild) == 1)
            Q.push(p->rchild);
    }
}

int Depth(BiTree T)   //树的深度
{
    if(!T)   return 0;
    return Depth(T->lchild)>Depth(T->rchild)?Depth(T->lchild)+1:Depth(T->rchild)+1;
}

int CountNode(BiTree T)  //树的总结点数
{
    if(T == NULL) return 0;
    return CountNode(T->lchild)+CountNode(T->rchild)+1;
}

int Leaf(BiTree T)     //树的总结点数
{
    if(T == NULL)
        return 0;
    else if((T->lchild == NULL)&&(T->rchild == NULL))
        return 1;
    else
        return Leaf(T->lchild)+Leaf(T->rchild);
}

int main(void)
{
    BiTree root;
    CreateBiTree(root);

    printf("非递归先序遍历二叉树:");
    PreOrder_Nonrecursive(root);
    printf("\n");

    printf("非递归中序遍历二叉树:");
    InOrderTraverse(root);
    printf("\n");

    printf("非递归后序遍历二叉树:");
    PostOrder_Nonrecursive(root);
    printf("\n");

    printf("非递归层序遍历二叉树:");//LeverTraverse(root);
    LeverTraverse(root);
    printf("\n");

    printf("二叉树的叶子结点个数为:%d\n",Leaf(root));
    printf("二叉树的总结点个数为:%d\n",CountNode(root));
    printf("二叉树的深度为:%d\n",Depth(root));
    return 0;
}


注意:创建二叉树顺序为先中心节点,然后左子树,然后右子树,到了叶子节点后要把它的左右子树分别赋值为0

比如二叉树为: 1

2

我们输入应为:1 2 0 0 0回车

分别输入两个二叉树来验证结果:

第一个二叉树为:






第二个二叉树为:


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: