二叉树系列(建树,前序,中序,后序,中序非递归,深度,叶子数,节点数)

来源:互联网 发布:apache jmeter 2.13 编辑:程序博客网 时间:2024/06/05 09:49

二叉树

                                         a

                                     /       \

                                 b            $

                            /         \     

                      c                  d

                   /    \               /       \  

                $      $            e            f

                                    /   \         /    \

                                 $     g      $       $

                                      /    \

                                     $    $

结点类型和指针

typedef char TElemType;typedef  struct  BiTNode{TElemType data;struct BiTNode  *lchild, *rchild;   //左右孩子指针} BiTNode, *BiTree;


① 创建二叉树CreatBiTree()

char Vexch[15]={'a','b','c','$','$','d','e','$','g','$','$','f','$','$','$'};int i=0;//二叉树的创建Status CreatBiTree(BiTree &T){if(Vexch[i++]=='$') T=NULL;else{T= new BiTNode;if(!T)  return 0;T->data=Vexch[i-1];//生成根节点CreatBiTree(T->lchild);//创建左子树CreatBiTree(T->rchild);//创建右子树}return 1;}

建立二叉树时:判断 i 是否为空 ,那么指针指向空

                        建树建完本结点后,首先先建左子树,左子树碰到叶子后,才往右边建右子树


② 先序遍历二叉树 PreOrderTraverse()

//先序遍历二叉树Status PreOrderTraverse(BiTree T,void( * visit)(TElemType)){if(T){visit(T->data);PreOrderTraverse(T->lchild,visit);PreOrderTraverse(T->rchild,visit);}return 1;}

判断本结点是否为空,非空就输出本结点的data(根),再输出左子树(左),再输出右子树(右):(根>左>右)


③ 中序遍历二叉树 InOrderTraverse()

//中序遍历二叉树Status InOrderTraverse(BiTree T,void( * visit)(TElemType)){if(T){InOrderTraverse(T->lchild,visit);visit(T->data);InOrderTraverse(T->rchild,visit);}return 1;}

判断本结点是否为空,非空先输出左子树(左),再输出本结点data(根),再输出右子树(右):(左>根>右)


④ 后序遍历二叉树 PostOrderTraverse()

//后序遍历二叉树Status PostOrderTraverse(BiTree T,void( * visit)(TElemType)){if(T){PostOrderTraverse(T->lchild,visit);PostOrderTraverse(T->rchild,visit);visit(T->data);}return 1;}
判断本节点是否为空,非空先输出左子树(左),再输出右子树(右),再输出本节点data(根):(左>右>根)

⑤ 释放子树 Destory()

//释放T所指子树,该函数在析构函数中被调用void Destory(BiTree T){if(T){Destory(T->lchild);Destory(T->rchild);delete T;}}

用后序遍历,释放子树。


⑥ 中序遍历非递归实现 InOrderNotRescure()

//中序遍历二叉树的非递归实现,visit为遍历操作函数void InOrderNotRescure(BiTree T,void( * visit)(TElemType)){stack<BiTree> S;while(!S.empty() || T!=NULL ){if(T!=NULL){S.push(T);T=T->lchild;}else {T=S.top();visit(T->data);S.pop();T=T->rchild;}}//end of while}
.利用栈,先将根节点存到栈里(暂不输出),然后往左子树探,探到最左后,没有左边之后(弹出栈,输出值),再往右边探。


⑦ 计算二叉树结点 NodesCount()

//计算二叉树结点int NodesCount(BiTree T){if(T == NULL) return 0;elsereturn NodesCount(T->lchild)+NodesCount(T->rchild)+1;}
用递归,每一个函数往左边和右边(顺序无关),两个方向探索,然后每探索成功一次,说明有一个结点,+1。出口为结点为空

⑧ 计算二叉树深度 Deepth()

//计算二叉树深度int Deepth(BiTree T){if(T == NULL) return 0;else{int left= Deepth(T->lchild);int right = Deepth(T->rchild);if(left > right) return left+1;else return right+1;}}
用递归,向左右探索(顺序无关),返回的值是二叉树的深度,分治思想,在左边和右边的子树那个深度大,那么就选那个深度大的+1 。出口为结点为空。


⑨ 计算二叉树叶子数目 LeafCount()

//计算二叉树的叶子数目int LeafCount(BiTree T){if(T == NULL) return 0;else if(T->lchild == NULL && T->rchild==NULL)return 1;elsereturn LeafCount(T->lchild)+LeafCount(T->rchild);}
递归,和探索结点一样,左右探索(顺序无关),结点左右子树皆为空,才是叶子。出口两个,结点为空返回0,结点的左右子树为空返回1。

(为什么要结点为空返回0?因为A的左子树这个情况的时候,就要返回0,B的情况返回1) 

        A

      /    \

    $      B

          /    \

       $        $


⑩ 主函数main()和visit()函数

void visit (char e){printf("%5c",e);}int main(){BiTree T;printf("1.建立二叉树\n");printf("二叉树:");CreatBiTree(T);printf("\n2.前序遍历二叉树\n");PreOrderTraverse(T,visit);printf("\n3.中序遍历二叉树\n");InOrderTraverse(T,visit);printf("\n4.后序遍历二叉树\n");PostOrderTraverse(T,visit);printf("\n5.非递归中序遍历二叉树\n");InOrderNotRescure(T,visit);printf("\n6.计算二叉树的深度\n");printf("树的深度为:%d\n",Deepth(T));printf("\n7.计算二叉树的叶子树\n");printf("树的叶子树为:%d\n",LeafCount(T));printf("\n8.计算二叉树的节点数\n");printf("树的节点数为:%d\n",NodesCount(T));return 0;}


结果:




0 0
原创粉丝点击