数据结构 第六章 树与二叉树.ppt
《数据结构 第六章 树与二叉树.ppt》由会员分享,可在线阅读,更多相关《数据结构 第六章 树与二叉树.ppt(104页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、树的定义和基本术语树的定义和基本术语二叉树二叉树(Binary Tree)二叉树的存储结构二叉树的存储结构遍历二叉树遍历二叉树(Binary Tree Traversal)线索化二叉树线索化二叉树(Threaded Binary Tree)树与森林树与森林(Tree&Forest)赫夫曼树赫夫曼树(Huffman Tree)二叉树的计数二叉树的计数6.1 树的定义和基本术语树的定义和基本术语1.树的定义树的定义 树是由树是由n(n 0)个结点组成的有限集合。个结点组成的有限集合。如果如果n=0,称为空树;称为空树;如果如果n 0,则则:有一个特定的称之为有一个特定的称之为根根(root)的结点
2、,它只的结点,它只有后继,但没有前驱;有后继,但没有前驱;除根以外的其它结点划分为除根以外的其它结点划分为m(m 0)个互不个互不相交的有限集合相交的有限集合T0,T1,Tm-1,每个集合本身每个集合本身又是一棵树,并且称之为根的又是一棵树,并且称之为根的子树子树(subTree)。每棵子树的根结点有且仅有一个每棵子树的根结点有且仅有一个直接直接前驱,但可前驱,但可以有以有0个或多个后继。个或多个后继。n n结点结点结点结点(node)(node)n n结点的度结点的度结点的度结点的度(degree)(degree)n n分支分支分支分支(branch)(branch)结点结点结点结点n n叶
3、叶叶叶(leaf)(leaf)结点结点结点结点n n孩子孩子孩子孩子(child)(child)结点结点结点结点n n双亲双亲双亲双亲(parent)(parent)结点结点结点结点n n兄弟兄弟兄弟兄弟(sibling)(sibling)结点结点结点结点n n祖先祖先祖先祖先(ancestor)(ancestor)结点结点结点结点n n子孙子孙子孙子孙(descendant)(descendant)结结结结点点点点n n结点所处层次结点所处层次结点所处层次结点所处层次(level)(level)n n树的深度树的深度树的深度树的深度(depth)(depth)n n树的度树的度树的度树的度(
4、degree(degree)n n 有序树有序树有序树有序树n n 无序树无序树无序树无序树n n 森林森林森林森林 1)度(次数、级)度(次数、级)(1)结点的度:一个结点所拥有的子数的个数)结点的度:一个结点所拥有的子数的个数 (2)树的度:树内各结点的度的最大值)树的度:树内各结点的度的最大值2)描述上下及左右的关系)描述上下及左右的关系 孩子结点:一个结点的子树的根孩子结点:一个结点的子树的根 双亲结点:双亲结点:P120 兄弟结点:同一个双亲的孩子之间互称兄弟兄弟结点:同一个双亲的孩子之间互称兄弟 祖先:结点的祖先是从根到该结点所经分支上的祖先:结点的祖先是从根到该结点所经分支上的
5、所有结点所有结点 子孙:子孙:P120结点的后代结点的后代3)层次)层次 (1)结点的层次)结点的层次 (2)树的深度(高度)树的深度(高度)2.树的基本术语树的基本术语树的基本操作:树的基本操作:p119树的建立和遍历树的建立和遍历重点重点树的抽象数据类型树的抽象数据类型6.2 二叉树二叉树(Binary Tree)二叉树的定义二叉树的定义二叉树的五种不同形态二叉树的五种不同形态 一棵二叉树是结点的一个有限集合,该一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根结点加上两集合或者为空,或者是由一个根结点加上两棵分别称为左子树和右子树的、互不相交的棵分别称为左子树和右子树的、互不
6、相交的二叉树组成。二叉树组成。特点:特点:1)每个结点的度)每个结点的度2;2)是有序树)是有序树基本操作:基本操作:p121p123二叉树的建立和遍历二叉树的建立和遍历二叉树的抽象数据类型二叉树的抽象数据类型性质性质1 若二叉树的层次从若二叉树的层次从1开始开始,则在二叉树的则在二叉树的第第 i 层最多有层最多有 2i-1个结点。个结点。(i 1)证明用数学归纳法证明用数学归纳法性质性质2 深度为深度为k的二叉树最多有的二叉树最多有 2k-1个结点。个结点。(k 1)证明用求等比级数前证明用求等比级数前k项和的公式项和的公式性质性质3 对任何一棵二叉树对任何一棵二叉树,如果其叶结点个数为如果
7、其叶结点个数为 n0,度为度为2的非叶结点个数为的非叶结点个数为 n2,则有则有 n0n21二叉树的性质二叉树的性质证明:证明:若设度为若设度为1的结点有的结点有n1个,总结点个个,总结点个数为数为n,总边数为总边数为e,则根据二叉树的定义,则根据二叉树的定义,n=n0+n1+n2 e=2n2+n1=n-1因此,有因此,有 2n2+n1=n0+n1+n2-1 n2=n0-1 n0=n2+1 同理:同理:三次树:三次树:n0=1+n2+2n3四次树:四次树:n0=1+n2+2n3+3n4K次树:次树:n0=1+n2+2n3+(k-1)nk定义定义1 满二叉树满二叉树(Full Binary Tr
8、ee)定义定义2 完全二叉树完全二叉树(Complete Binary Tree)若设二叉树的深度为若设二叉树的深度为h,则共有则共有h层。除第层。除第h层层外,其它各层外,其它各层(0 h-1)的结点数都达到最大个数,的结点数都达到最大个数,第第h层从右向左连续缺若干结点,这就是完全二层从右向左连续缺若干结点,这就是完全二叉树。叉树。性质性质4 具有具有n个结点的完全二叉树的深度为个结点的完全二叉树的深度为 log2n +1证明:证明:设完全二叉树的深度为设完全二叉树的深度为k,则有则有 2k-1-1 n 2k-1 2k-1 n 2k 取对数取对数 k-1 log2n 1,则则 i 的双亲为
9、的双亲为 i/2 n n 若若2*i n,则则 i 的左孩子为的左孩子为2*i,否则无左孩子否则无左孩子 若若2*i+1 n,则则 i 的右孩子为的右孩子为2*i+1,否则无右否则无右孩子孩子n n 若若 i 为偶数为偶数,且且i!=n,则其右兄弟为则其右兄弟为i+1 若若 i 为奇数为奇数,且且i!=1,则其左兄弟为则其左兄弟为i-1n n i 所在层次为所在层次为 log2 i +1完全二叉树的数组表示完全二叉树的数组表示 一般二叉树的数组表示一般二叉树的数组表示二叉树的存储结构二叉树的存储结构1.顺序存储结构(数组表示)顺序存储结构(数组表示)#define MAX_TREE_SIZE
10、100typedef TElemType SqBiTreeMAX_TREE_SIZE;SqBiTree bt;由于一般二叉树必须仿照完由于一般二叉树必须仿照完全二叉树那样存储,可能会全二叉树那样存储,可能会浪费很多存储空间,单支树浪费很多存储空间,单支树就是一个极端情况。就是一个极端情况。单支树单支树2.2.链式存储结构链式存储结构typedef struct BiTNode /二叉链表的定义TElemType data;Struct BiTNode*lchild,*rchild;BiTNode,*BiTree;二叉树链表表示的示例二叉树链表表示的示例3.静态二叉链表和静态三叉链表静态二叉链表
11、和静态三叉链表预先开辟空间,用数组表示leftChild,rightChild数组元素的下标6.3 遍历二叉树遍历二叉树 (Traversing Binary Tree)p128 所谓树的遍历,就是按某种次序访问树中的结点,所谓树的遍历,就是按某种次序访问树中的结点,所谓树的遍历,就是按某种次序访问树中的结点,所谓树的遍历,就是按某种次序访问树中的结点,要求每个结点访问一次且仅访问一次。要求每个结点访问一次且仅访问一次。要求每个结点访问一次且仅访问一次。要求每个结点访问一次且仅访问一次。遍历的结果:遍历的结果:遍历的结果:遍历的结果:产生一个关于结点的线性序列。产生一个关于结点的线性序列。产生
12、一个关于结点的线性序列。产生一个关于结点的线性序列。设设设设访问根结点访问根结点访问根结点访问根结点记作记作记作记作 D D 遍历根的左子树遍历根的左子树遍历根的左子树遍历根的左子树记作记作记作记作 L L 遍历根的右子树遍历根的右子树遍历根的右子树遍历根的右子树记作记作记作记作 R R 则可能的遍历次序有则可能的遍历次序有则可能的遍历次序有则可能的遍历次序有 先序先序先序先序 DLR DRL DLR DRL 逆先序逆先序逆先序逆先序 中序中序中序中序 LDR RDL LDR RDL 逆中序逆中序逆中序逆中序 后序后序后序后序 LRD RLDLRD RLD 逆后序逆后序逆后序逆后序先序遍历先序
13、遍历(Preorder Traversal)先序遍历二叉树算法的框架先序遍历二叉树算法的框架是是n n若二叉树为空,则空操作;若二叉树为空,则空操作;n n否则否则uu访问根结点访问根结点(D);uu先序遍历左子树先序遍历左子树(L);uu先序遍历右子树先序遍历右子树(R)。遍历结果(前缀表达式)遍历结果(前缀表达式)-+a*b-c d/e f在波兰式中,自左到右在波兰式中,自左到右依次扫描:连续出现依次扫描:连续出现2个操作数时,将其前面个操作数时,将其前面的运算符退出,对该两的运算符退出,对该两操作数进行这两个操作操作数进行这两个操作数前面的运算符的运算,数前面的运算符的运算,运算的中间结
14、果进栈,运算的中间结果进栈,然后再进行上述的操作。然后再进行上述的操作。先序遍历二叉树的递归算法先序遍历二叉树的递归算法void PreOrderTraverse(BiTree T)if(T)printf(%c,T-data);PreOrderTraverse(T-lchild);PreOrderTraverse(T-rchild);中序遍历二叉树算法的框架是:中序遍历二叉树算法的框架是:n n若二叉树为空,则空操作;若二叉树为空,则空操作;n n否则否则uu中序遍历左子树中序遍历左子树(L);uu访问根结点访问根结点(D);uu中序遍历右子树中序遍历右子树(R)。遍历结果(中缀表达式)遍历结
15、果(中缀表达式)a+b*c-d-e/f中序遍历中序遍历(Inorder Traversal)表达式语法树表达式语法树中序遍历二叉树的递归算法中序遍历二叉树的递归算法void InOrderTraverse(BiTree T)if(T)InOrderTraverse(T-lchild);printf(%c,T-data);InOrderTraverse(T-rchild);后序遍历后序遍历(Postorder Traversal)后序遍历二叉树算法的框架是后序遍历二叉树算法的框架是n n若二叉树为空,则空操作;若二叉树为空,则空操作;n n否则否则uu后序遍历左子树后序遍历左子树(L);uu后序
16、遍历右子树后序遍历右子树(R);uu访问根结点访问根结点(D)。在逆波兰式中,自左到在逆波兰式中,自左到右依次扫描:是操作数,右依次扫描:是操作数,则依次进栈;遇到运算则依次进栈;遇到运算符。则退出两个操作数,符。则退出两个操作数,对该两操作数进行该运对该两操作数进行该运算符的运算,运算的中算符的运算,运算的中间结果进栈;然后再继间结果进栈;然后再继续重复上述的操作。续重复上述的操作。遍历结果(后缀表达式)遍历结果(后缀表达式)a b c d-*+e f/-后序遍历二叉树的递归算法后序遍历二叉树的递归算法void PostOrderTraverse(BiTree T)if(T)PostOrde
17、rTraverse(T-lchild);PostOrderTraverse(T-rchild);printf(%c,T-data);由二叉树的先序序列和中序序列可唯一地确定一由二叉树的先序序列和中序序列可唯一地确定一棵二叉树。棵二叉树。例例,先序序列先序序列 ABHFDECKG 和和中序序列中序序列 HBDFAEKCG,构造二叉树过程如构造二叉树过程如下:下:遍历二叉树的非递归算法遍历二叉树的非递归算法n先序遍历:算法1,将右子树根结点 入栈,(栈所需最大容量为n/2+1);算法2将根结点入栈 n中序遍历:在遍历左子树之前,先把根结点入栈,当左子树遍历结束后,从栈中弹出,访问,再遍历右子树n后
18、序遍历:1)设定一个指针,指向 最近访问过的结点。在退栈取出根结点时,需判断:若根结点的右子树为空,或它的右子树非空,但已遍历完毕,即它的右子树根结点恰好是最近一次访问过的结点时,应该遍历该根结点。反之,该根结点应重新入栈,先遍历它的右子树。2)还可同时设定一个标记,指示该根结点是第一次还是第二次入栈n需用到栈,顺序栈的定义如下:typedef BiTNode*SElemType;typedef structSElemType*base;SElemType*top;int stacksize;SqStack;先序遍历的非递归算法先序遍历的非递归算法void preorder(BiTree T)
19、SqStack S;BiTree P=T;InitStack(S);Push(S,NULL);while(P)printf(%c,P-data);if(P-rchild)Push(S,P-rchild);if(P-lchild)P=P-lchild;else Pop(S,P);先序遍历的非递归算法先序遍历的非递归算法2void preorder(BiTree T)int top=0;BiTree stack20,P=T;do while(P)printf(%c,P-data);stacktop=P;top+;P=P-lchild;if(top)top-;P=stacktop;P=P-rchil
20、d;while(top|P);中序遍历的非递归算法中序遍历的非递归算法1void inorder(BiTree T)SqStack S;BiTree P=T;InitStack(S);dowhile(P)*(S.top)=P;S.top+;P=P-lchild;if(S.top)S.top-;P=*(S.top);printf(%c,P-data);P=P-rchild;while(S.top!=S.base)|P);中序遍历的非递归算法中序遍历的非递归算法2(p131算法算法6.3)void inorder(BiTree T)SqStack S;BiTree P=T;InitStack(S)
21、;while(P|!Empty(S)if(P)Push(S,P);P=P-lchild;else Pop(S,P);printf(%c,P-data);P=P-rchild;后序遍历时,每遇到一个结点,先把它推入栈后序遍历时,每遇到一个结点,先把它推入栈中,让中,让PopTim=0。在遍历其左子树前,改结点的在遍历其左子树前,改结点的PopTim=1,将其左孩子推入栈中。在遍历完左子将其左孩子推入栈中。在遍历完左子树后,还不能访问该结点,必须继续遍历右子树,树后,还不能访问该结点,必须继续遍历右子树,此时改结点的此时改结点的PopTim=2,并把其右孩子推入栈中。并把其右孩子推入栈中。在遍历完
22、右子树后,结点才退栈访问。在遍历完右子树后,结点才退栈访问。后序遍历的非递归算法后序遍历的非递归算法1void Postorder(BiTree T)BiTree p=T,q=NULL;SqStack S;InitStack(S);Push(S,p);while(!StackEmpty(S)if(p&p!=q)Push(S,p);p=p-lchild;else Pop(S,p);if(!StackEmpty(S)if(p-rchild&p-rchild!=q)Push(S,p);p=p-rchild;else printf(%c,p-data);q=p;后序遍历的非递归算法后序遍历的非递归算法
23、2void postorder(BiTree T)BiTree P=T,q;int flag;SqStack S;InitStack(S);do while(P)*(S.top)=P;S.top+;P=P-lchild;q=NULL;flag=1;while(S.top!=S.base)&flag)P=*(S.top-1);if(P-rchild=q)printf(%c,P-data);S.top-;q=p;else P=P-rchild;flag=0;while(S.top!=S.base);先序建立二叉树的递归算法先序建立二叉树的递归算法(p131,算法算法6.4)Status Creat
24、eBiTree(BiTree&T)char ch;scanf(%c,&ch);if(ch=)T=NULL;else if(!(T=(BiTNode*)malloc(sizeof(BiTNode)exit(OVERFLOW);T-data=ch;CreateBiTree(T-lchild);CreateBiTree(T-rchild);return OK;二叉树的显示输出二叉树的显示输出void PrintBiTree(BiTree T,int n)int i;char ch=;if(T)PrintBiTree(T-rchild,n+1);for(i=1;idata);PrintBiTree(T
25、-lchild,n+1);说明:说明:1)遍历的第一个和最后一个结点)遍历的第一个和最后一个结点第一个结点:第一个结点:先序:先序:根结点;根结点;中序:中序:沿着左链走,找到一个没有左孩子的结点;沿着左链走,找到一个没有左孩子的结点;后序:后序:从根结点出发,沿着左链走,找到一个既没从根结点出发,沿着左链走,找到一个既没有左孩子又没有右孩子的结点。有左孩子又没有右孩子的结点。最后一个结点:最后一个结点:中序:中序:从根结点出发,沿着右链走,找到一个没有从根结点出发,沿着右链走,找到一个没有右孩子的结点;右孩子的结点;后序:后序:根结点。根结点。n先序:从根结点出发,沿着右链走,找到一个没有右
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 第六章 树与二叉树 第六 二叉
限制150内