1、第6章树6.4二叉树的遍历二叉树的遍历! 令L,r和R代表访问左子树,访问根结点、右子树。! 遍历有六种可能的组合LRr,LrR,rLR,RLr,RrL,rRL! 约定先左后右遍历,仅剩下3中种遍历顺序LRr,LrR,rLR! 后根序遍历、中根序遍历、先根序遍历深度优先遍历Data Structure先根序遍历 若二叉树非空(1)访问根结点(2)先根序遍历左子树(3)先根序遍历右子树Algorithm PreOrder(v)if(v非空) visit(v);PreOrder (leftChild (v);PreOrder (rightChild (v);532618 974先根序遍历过程tem
2、plate void BinaryTree :PreOrder ( ) PreOrder ( root );template void BinaryTree:PreOrder ( BinTreeNode *current ) if ( current != NULL ) cout currentdata;PreOrder ( currentleftChild );PreOrder ( currentrightChild );先根序遍历算法的实现中根序遍历 若二叉树非空(1)中根序遍历左子树(2)访问根结点(3)中根序遍历右子树Algorithm inOrder(v)if(v非空) inOrde
3、r (leftChild (v);visit(v);inOrder (rightChild (v);312567 984中根序遍历过程template void BinaryTree :InOrder ( ) InOrder ( root );template void BinaryTree : InOrder ( BinTreeNode *current ) if ( current != NULL ) InOrder ( currentleftChild );cout currentdata;InOrder ( currentrightChild );中根序遍历算法实现后根序遍历 若二叉树
4、非空(1)后根序遍历左子树(2)后根序遍历右子树(3)访问根结点Algorithm PostOrder(v)if(v非空) PostOrder (leftChild (v);PostOrder (rightChild (v);visit(v);215396 784template voidBinaryTree :PostOrder( ) PostOrder( root );template void BinaryTree:PostOrder( BinTreeNode *current ) if ( current != NULL ) PostOrder( currentleftChild);P
5、ostOrder( currentrightChild);cout currentdata;后根序遍历算法的实现试一下12 34 5 6先跟序列: ?中根序列 ?后根序列 ?71012 34 5698计算二叉树结点个数 若二叉树为空返回0 若二叉树非空问题分解求解(1)l=递归递归求左子树个数(2)r=递归调用求右子树个数解的合并返回l+r+1template int BinaryTree : Size ( constBinTreeNode *t ) const if( t = NULL ) return0;elsereturn1 + Size ( tleftChild )+ Size ( t
6、rightChild );计算二叉树高度 若二叉树为空返回-1 若二叉树非空(1)lh=递归递归求左子树个数(2)rh=递归调用求右子树个数返回max(lh,rh)+1template int BinaryTree : Depth ( const BinTreeNode *t ) const if ( t = NULL ) return -1;else return 1 + Max ( Depth ( tleftChild ), Depth ( trightChild ) );一个二叉树的先根序列:ABECDFGHIJ二叉树的中根序列:EBCDAFHIGJ 求二叉树的结构?ABECDFGHIJ
7、 ABECDFGHIJ ABECDFGHIJEBCDAFHIGJ EBCD FHIGJ E CD HIGJAEBCD FHIGJABECD HIGJFABEHIGJFCD根据两种序列确定二叉树的结构输入二叉树的先根序遍历顺序能否将实例输入计算机?AFEDCB*使用*说明空树A B D * F * * * C E * * *先根序遍历顺序:A B D F C E 如何创建二叉树?template void BinaryTree : CreateBinaryTree () CreateBinaryTree(root);通过先根序遍历顺序创建二叉树template void BinaryTree :
8、 CreateBinaryTree (BiTreeNode * &T) scanf(&ch); /get a charif (ch=*) T=NULL; /if it denotes an empty treeelse if (!(T= new BiTreeNode()exit(1); /allocated failedT-data = ch;CreateBiTree(T-leftChild); /creates its left subtreeCreateBiTree(T-rightChild); /creates its right subtreereturn OK;通过先根序遍历顺序创建
9、二叉树递归VS非递归 函数调用时用运行时栈保存返回地址 调用者将参数放在栈中,并将控制权传 调用者。 在运行时栈 存 有运行时栈保 可 顺 行 但是控制转移有时间开销 运行时栈有空间开销a +*/d -Te b c Caller:遍历T为根的二叉树InorderTraverse(BinTreT) if (T) InorderTraverse(T-lchild); printf(“%c”,T-data);InorderTraverse(T-rchild); TLCale:遍历TL为根的二叉树InorderTraverse(BinTreT) if (T) InorderTraverse(T-lch
10、ild); printf(“%c”,T-data);InorderTraverse(T-rchild); TLT返回地址TL返回地址栈非递归遍历 用 栈 遍历 栈代运行时栈,用 存 返回的结点 二叉树的遍历 (DLR遍历过程6)ac df ghnw o u m xuf o cgm ax n dha的指针c的指针f的指针w的指针wog非递归遍历算法的实现template void BinaryTree : InOrderTraverse () stack S; BiTreeNode * p;S.makeEmpty( ); p = root; /初始化dowhile ( p ) S.push(p)
11、; p = pleftChild; if ( !S.empty( ) ) /栈非空p = S.top( ); S.pop( ); /退栈cout pdata; /访问根结点p = prightChild; /向右链走 while ( p | !S.empty( ) );template void BinaryTree : InOrderTraverse () stack S; BiTreeNode * p;S.makeEmpty( ); p = root; /初始化dowhile ( p ) S.push(p); p = pleftChild; if ( !S.empty( ) ) /栈非空p
12、 = S.top( ); S.pop( ); /退栈cout pdata; /访问根结点p = prightChild; /向右链走 while ( p | !S.empty( ) );非递归遍历算法的实现template void BinaryTree : InOrderTraverse () stack S; BiTreeNode * p;S.makeEmpty( ); p = root; /初始化dowhile ( p ) S.push(p); p = pleftChild; if ( !S.empty( ) ) /栈非空p = S.top( ); S.pop( ); /退栈cout p
13、data; /访问根结点p = prightChild; /向右链走 while ( p | !S.empty( ) );非递归遍历算法的实现! 层次由小到大! 内层从左到右! 采用队列辅助遍历层序遍历template void BinaryTree:LevelOrder( ) QueueBiTreeNode * qu;if(root = NULL) return;qu.EnQueue(root);while( !q.IsEmpty ( ) ) current = qu.DeQueue ( ); /退队coutdata;if( currentleftChild != NULL ) /左子女qu.EnQueue ( currentleftChild); /进队列if( currentrightChild != NULL ) /右子女qu.EnQueue ( currentrightchild ); /进队列层序遍历算法的实现