1、第6章 树和二叉树第6章 树和二叉树6.1 树的定义和基本术语树(Tree)是n(n0)个结点的有限集。在任意一棵非空树中:1)有且仅有一个特定的称为根(Root)的结点;2)当n1时,其余结点可分为m(m0)个互不相交的有限集T1,T2,,Tm,其中每一个集合本身又是一棵树,并且称为根的子树(SubTree)。其中A是整棵树的根,而B、C、D等就是A的子树。结点:结点的度:以该结点为根的子树的数目,如D有三棵子树,D的度为3.树的度:一棵树中,某个结点的度最大就是树的度。叶子:又称终端结点,指没有孩子的结点。如K、L、F等。非终端结点:有孩子的结点。如E、C、D等。孩子:结点子树的根称为孩子
2、。双亲(有时称父结点,有时又称母结点):兄弟:同一个双亲的孩子之间互称为兄弟,如H、I、J都是D的孩子,那么H、I、J互称为兄弟。祖先:D和A是M的祖先。子孙:E、F、K等都是A的子孙。层次:从根开始称为第1层,根的孩子为第2层,如此之般。堂兄弟:如果双亲在同一层的结点互为堂兄弟。如:M与K、L互称为堂兄弟。深度:树中结点的最大层次称为树的深度。上图深度为4,又称为高度。有序树:如果一棵树的每个结点,其若干个孩子中,左右顺序不能互换,称为有序树。无序树:在有序树中,最左边的那个孩子称为第一个孩子,最右边的那个称为最后一个孩子。森林:由若干棵(0或1或多棵)互不相交的树构成的。6.2 二叉树6.
3、2.1 二叉树的定义二叉树(Binary Tree),是一棵特殊的树:每个结点的度都不超过2(0、1、2),且是有序树。其左右孩子不能交换位置。二叉树有5种基本形态:题目:已知一棵二叉树有3个结点,问有几种可能形态?思考:有n个结点的二叉树有几种可能的形态?答:种形态6.2.2 二叉树的性质性质1:在二叉树的第i层上至多有2i-1个结点(i=1)性质2:深度为k的二叉树至多有2k-1个结点。性质3:对任何一棵二叉树T,如果其终端(叶子)结点数为n0,度为2的结点数为n2,则有公式:n0=n2+1证明:一方面,结点的总数n=n0+n1+n2另一方面:结点的总数n=B+1,而边数Bn2*2+n1*
4、1+n0*0所以: n0+n1+n22n2+n1+1n0=n2+1完全二叉树:如果一棵二叉树,它的编号与满二叉树完全一致。其特点:1) 叶子只可能在最后两层上;2) 对任一结点,若其右分支下的子孙的最大层次为l,则左分支下的子孙最大层次必为l或l+1。1满二叉树:如果有一棵二叉树,它的每一层的结点个数恰好为最多的可能个数,也就是第i层上有2i-1个结点,这样的二叉树称为满二叉树。形象地说,就是一棵二叉树满满的。对于满二叉树,可以对结点进行编号,从上往下,从左往右进行。性质4:具有n个结点的完全二叉树的深度为(向下取整为不大于该数的最大整数,如2.69结果为2,类似的还有向上取整,取不小于该数的
5、最小整数,如3)证明:设该树的深度为k,根据性质2及完全二叉树的定义有:性质5:对于一棵有n个结点的完全二叉树,如果按照上面的编号,则:1)如果i=1,则结点i是根,它没有双亲;如果i1,则它有双亲,其双亲结点编号为 2)如果i很大,2in,则结点i无左孩子,且该结点为叶子;否则,如果i不大,2in,则结点i无右孩子;否则,如果i不大,2i+1data ); /访问T; PreOrderTraverse(T-lchild ); /再以前序方式访问T-lchild; PreOrderTraverse(T-rchild ); /再以前序方式访问T-rchild; return OK;对于非递归方式
6、,需要用栈。A、B、E、L、D、H、O、JStatus PreOrderTraverse_2( BiTree *T ) /非递归方式前序遍历二叉树T InitStack( S ); if( T=NULL ) return ERROR; /如果T本身是空树,无法访问 Push( S, T ); /根入栈 while( !EmptyStack( S ) ) /如果栈不空,继续循环 Pop( S, p ); printf( p-data ); /访问p if( p-rchild!=NULL) /如果p的左孩子不空,则入栈 Push( S, p-rchild ); if( p-lchild!=NULL
7、 ) Push( S, p-lchild ); return OK;2、中序(又称中根),它的进程是: 1)先用中序方式遍历其左子树; 2)再访问它; 3)再用中序方式遍历其右子树;以T1为例,可得到顺序:E、L、B、A、O、H、D、J算法的实现,仍然有递归与非递归方式,递归方式:Status InOrderTraverse( BiTree *T ) /递归方式中序遍历二叉树T if( T!=NULL ) InOrderTraverse(T-lchild ); /再以中序方式访问T-lchild; printf( T-data ); /访问T; InOrderTraverse(T-rchild
8、 ); /再以中序方式访问T-rchild; return OK;非递归算法:Status InOrderTraverse_2( BiTree *T ) /非递归方式中序遍历二叉树T InitStack( S ); p=T; if( T=NULL ) return ERROR; /如果T本身是空树,无法访问 while( !EmptyStack( S ) | p!=NULL ) while( p!=NULL ) /p的所有的左子树依次入栈 Push( S, p ); p=p-lchild; if( !EmptyStack( S ) ) Pop( S, p ); printf( p-data )
9、; p=p-rchild; return OK;E、L、B、A3、后序(又称后根),它的进程是: 1)先用后序方式遍历其左子树; 2)再用后序方式遍历其右子树; 3)再访问它;Status PostOrderTraverse( BiTree *T ) /递归方式后序遍历二叉树T if( T!=NULL ) PostOrderTraverse(T-lchild ); /再以后序方式访问T-lchild; PostOrderTraverse(T-rchild ); /再以后序方式访问T-rchild; printf( T-data ); /访问T; return OK;4、层次遍历,它的进程是从根
10、开始,从上到到,从左至右依次访问:以T1为例,可得顺序:A、B、D、E、H、J、L、O其算法可用非递归实现,借助队列来实现。A、B、D、E、H、J、L、OStatus LevelOrderTraverse( BiTree *T ) /层次遍历二叉树T if( T=NULL ) return ERROR; InitQueue( Q ); EnQueue( Q, T ); while( !EmptyQueue( Q ) ) DeQueue( Q, p ); /出队 printf( p-data ); if( p-lchild !=NULL ) EnQueue( Q, p-lchild ); if(
11、 p-rchild !=NULL ) EnQueue( Q, p-rchild ); return OK;5、补充算法:如何交换一棵二叉树的所有左、右孩子有递归和非递归的算法,下面先看递归:递归的思想与前序遍历很相似,每访问一个结点,就将该结点的左右孩子进行交换,再用递归对其左子树进行交换、右子树进行交换:Status ExchangeBiTree( BiTree &T ) if( T!=NULL ) s=T-lchild; T-lchild=T-rchild; T-rchild=s; /交换T的左右孩子; ExchangeBiTree( T-lchild ); /再调用函数,交换其左子树;
12、ExchangeBiTree( T-rchild ); /再调用函数,交换其右子树; return OK;非递归算法,与前序遍历又非常相似。Status ExchangeBiTree_2( BiTree &T ) if( T=NULL ) return ERROR; InitStack( S ); Push( S, T ); while( !EmptyStack( S ) ) Pop( S, p ); p-lchildp-rchild; if(p-lchild!=NULL) Push(S, p-lchild); if(p-rchild!=NULL) Push(S, p-rchild); ret
13、urn OK;6、补充算法:二叉树在数学表达式计算中的应用在栈与队列一章中,介绍过用栈来计算数学表达式。如:a+b*(c-d)-e/f,的中缀表示,它用中序遍历可得:a+b*c-d-e/f,如果用后序遍历,可得:abcd-*+ef/-,又称为后缀表示,也称为逆波兰式。如果用前序遍历:-+a*b-cd/ef,又称为前缀表示(波兰式)。(a*(b+c/(d-e)-f)+g)*l7、创建二叉树可用递归与非递归的方法,对于递归算法:用户如果输入:ABE#L#DHO#J#,则可得二叉树:Status CreateBiTree( BiTree &T, char *str ) static char *ch=str; if( ch=# ) T=NULL; ch+; else T=(BiTNode*) malloc( sizeof( BiTNode ); T-data=ch; ch+; CreateBiTree( T-lchild ); CreateBiTree( T-rchild ); return OK;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1