数据结构树的讲解

上传人:pu****.1 文档编号:570169530 上传时间:2024-08-02 格式:PPT 页数:32 大小:202.52KB
返回 下载 相关 举报
数据结构树的讲解_第1页
第1页 / 共32页
数据结构树的讲解_第2页
第2页 / 共32页
数据结构树的讲解_第3页
第3页 / 共32页
数据结构树的讲解_第4页
第4页 / 共32页
数据结构树的讲解_第5页
第5页 / 共32页
点击查看更多>>
资源描述

《数据结构树的讲解》由会员分享,可在线阅读,更多相关《数据结构树的讲解(32页珍藏版)》请在金锄头文库上搜索。

1、64 树和森林树和森林 6.4.1树的存储结构 一、双亲表示法(顺序存储) /-树的双亲表存储表示-/ #define MAX_TREE_SIZE 100 typedef struct PTNode TElemType data; int parent; /双亲位置域 PTNode; typedef struct PTNode nodesMAX_TREE_SIZE; int n; /结点数 PTree;双亲表示法举例RADEFCBGKHR -1 A 0 B 0 C 0 D 1 E 1 F 3 G 6 H 6 K 6 0123456789数组下标:* 便于涉及双亲的操作;* 求结点的孩子时需要遍

2、历整棵树。6.4.1树的存储结构二、孩子表示法(顺序存储) #define MAX_TREE_SIZE 100 typedef struct PTNode TElemType data; int child1; /第1个孩子位置域 int child2; /第2个孩子位置域 . int childd; /第d个孩子位置域 PTNode; typedef struct PTNode nodesMAX_TREE_SIZE; int n; /结点数 PTree;孩子表示法举例RADEFCBGKH0123456789数组下标:* 便于涉及孩子的操作;求双亲不方便;* 采用同构的结点,空间浪费。R 1

3、A 4 B 0 C 6 D 0 E 0 F 7 G 0 H 0 K 0 2 3 5 0 0 0 0 0 0 0 0 0 8 9 0 0 0 0 0 0 孩子链表存储表示(链式存储) typedef struct CTNode /孩子结点 int child; struct CTNode *next; *ChildPtr; typedef struct TElemType data; ChildPtr firstchild; /孩子链表头指针 CTBox; typedef struct CTBox nodesMAX_TREE_SIZE; int n, r; /结点数和根的位置 CTree;孩子链

4、表存储表示举例RADEFCBGKH0123456789数组下标:* 便于涉及孩子的操作;* 求结点的双亲时不方便。R A B / C D / E / F G / H / K /1 2 3 / 4 5 / 6 / 7 8 9 / T.nodes ; T.n=10; T.r = 0;例1: 设树T以孩子链表为存储结构,寻找值为x的双亲结点的算法如下:Status parent(Ctree T, TElemType x)/ 当值为x的结点不存在时返回-2; / 当值为x的结点为根结点时返回-1, / 否则返回x结点的双亲结点的下标值. if(T.nodesT.r.data = x) return 1

5、; /值为x的结点为根结点; for(i=0;ichild.data != x) p = p-next; if(p) return (i); / 找到x的双亲结点 return 2; / 值为x的结点不存在例2: 删除值为x的结点的第i棵子树的算法delete如下:void deletej(Ctree &T, int j)/ 删除树T的第j号结点及其子树 if(!T.nodesj.firstchild) / 删除叶结点 for(i=j; inext;i = s-child; free(s);deletej(T, i); / 递归删除第i号结点及其子树 Status delete(Ctree &

6、T, TElemType x, int i) / 当值为x的结点不存在时返回-2;当值为x的结点为 /叶结点或无第i 棵子树时返回-1, 否则返回1. for(k=0; k=T.n) return 2; / 值为x的结点不存在 p= T.nodesk.firstchild; j = 1; if(!p) return 1; / x结点为叶结点 if(i=1) / 删除长子时,特殊处理 j =p-child; / 记住要删除子树的下标 T.nodesk.firstchild = p-next; free(p); else while(p-next & jnext ; j+; if(ji-1 | !

7、p-next) return 1; / 无第i 棵子树 / p指向第i-1 个儿子 j = p-next-child; / 记住要删除子树的下标 s = p-next; p-next = s-next; free(s); deletej(T, j); / 递归删除第j号结点及其子树 return 1;三.孩子兄弟表示法-树的二叉树表示法(二叉链表示法)b/-树的二叉链表(孩子兄弟)存储表示- typedef struct CSNode ELemType data; struct CSNode *firstchild,*nextsibling; CSNode, *CSTree;RADEFCBGK

8、HR/A/DE/C/H/F/G/B/K/孩子兄弟表示法示例:6.4.2 森林与二叉树的转换森林与二叉树的转换一.森林转换成二叉树b如果F=T1,T2, ,Tm是森林,则可按如下规则转换成一棵二叉树B=(root,LB,RB)。b (1)若F为空,即m=0,则B为空树;b (2)若F非空,即m0,则B的根root即为森林中第一棵树的根ROOT(T1);b B的左子树LB是从T1中根结点的子树森林F1=T11,T12, ,T1m1转换而成的二叉树;b 其右子对RB是从森林F=T2,T3, ,Tm 转换而成的二叉树.二. 二叉树转换成森林b如果B=(root,LB,RB)是一棵二叉树,则可按如下规则

9、转换成森林F=T1,T2, ,Tm:b (1)若B为空,则F为空;b (2)若B非空,则F中第一棵树T1的根ROOT(T1)即为二叉树B的根root;b T1中的根结点的子树森林 F1是由B的左子树LB转换而成的森林;b F中除T1之外其余树组成的森林F=T2,T3, ,Tm是由B的右子树RB转换而成的森林。6.4.3 树和森林的遍历树和森林的遍历b 树的两种遍历方法:b一、先根遍历:b (1)访问树的根结点;b (2)依次先根遍历每棵子树。b R A D E B C F G H Kb二、后根遍历:b(1)依次后根遍历每棵子树。b(2)访问树的根结点;b D E A B G H K F C R

10、 RADEFCBGKH森林的两种遍历方法:b 一、先序遍历森林:b 若森林非空,则b (1)访问森林中第一棵树的根结点;b (2)先序遍历第一棵树的根结点的子树森林;b (3)先序遍历除去第一棵树之后的森林。b二、中序遍历森林:b 若森林非空,则b(1)中序遍历第一棵树的根结点的子树森林;b (2)访问森林中第一棵树的根结点;b (3)中序遍历除去第一棵树之后的森林。6.6 赫夫曼树及其应用6.6.1最优二叉树(赫夫曼树)b 路路径径长长度度: 从树中一个结点到另一个结点之间的分支构成这两个结点之间的路径,路径上的分支数目称做路径长度。b 树树的的路路径径长长度度: 树的路径长度是从树根到每一

11、结点的路径长度之和。b 树树的的带带权权路路径径长长度度: 树的带权路径长度为树中所有叶子结点(k)的带权路径长度kk之和,b通常记作: nb WPL= kk。b k=1 最优二叉树或赫夫曼(Huffman)树的定义b假设有n个权值1, 2, , n,试构造一棵有n个叶子结点的二叉树,每个叶子结点带权为i, 则其中:b带权路径长度WPL最小的二叉树称做b 最优二叉树最优二叉树b 或赫夫曼树赫夫曼树.例1:下面三棵二叉树的四个叶子结点a,b,c,d的权值为7、5、2、4abcd7524abcd7524cdab7524(a)WPL=7x2+5x2+2x2+4x2 = 36(b)WPL=7x3+5x

12、3+2x1+4x2 = 46(c)WPL=7x1+5x2+2x2+4x2 = 35例2 最佳判定方法(p.144)(a)WPL=10x4+30x4+40x3+15x2+5x1=315(b)WPL=5x3+15x3+40x2+30x2+10x2=22010c90ed51540ba30607080NNNNYYYYY107090ec54015ba3060d0),构造赫夫曼树HT,并求出n个字符的赫夫曼编码HC.b if(n=1) return;bm=2*n-1;bHT=(HuffmanTree)malloc(m+1)*sizeof(HTNode);/0号单未用b for(p=HT,i=1;i=n;+

13、i,+p,+w) *p=*w,0,0,0;b for(;i=m;+i,+p) *p=0,0,0,0;求赫夫曼编码的算法(续一):b for(i=n+1;i=m;+i) /建赫夫曼树b /在HT1.i-1选择parent为0且weight最小的两个结点,b / 其序号分别为s1和s2.b select(HT,i-1,s1,s2);b HTs1.parent=i;HTs2.parent=i;b HTi.lchild=s1;HTi.rchild=s2;b HTi.weight=HTs1.weight+HTs2.weight;bb/-从叶子到根逆向求每个字符的赫夫曼编码-b Hc=(HffmanCod

14、e)malloc(n+1*sizeof(char *); /分配n个字符编码的头指针向量b cd=(char *)malloc(n*sizeof(char);/分配求编码的工作空间b cdn-1=/0; /编码结束符.求赫夫曼编码的算法(续二):b for(i=1;i=n;+i)/逐个字符求赫夫曼编码b start=n-1;/编码结束符位置b for(c=i,f=HTi;f!=0;c=f,f=Htf.parent)b /从叶子至根逆向求编码b if(HTf.lchild=c) cd-start=0;b else cd-start=1;b Hci=(char *)malloc(n-start)*

15、sizeof(char);b /为第i个字符编码分配空间b strcpy(HCi,&cdstart); /从cd复制编码(串)到HCb b free(cd); /释放工作空间b/HuffanCoding 求赫夫曼编码的算法如下:b/-无栈非递归遍历赫夫曼树,求赫夫曼编码bHC=(HuffmanCode)malloc(n+1)*sizeof(char *);bp=m;cdlen=0;bfor(i=1;i=m;+i)b HTi.weight=0; /遍历赫夫曼树时用作结点状态标志bwhile(p)b if(HTp.weight=o)/向左b Htp.weight=1;b if(HTp.lchild

16、!=0)p=HTp.lchild;cdcdlen+=0;b else if(HTp.rchild=0)/登记叶子结点的字符的编码b HCp=(char *)malloc(cdlen+1) *sizeof(char);b cdcdlen=0;strcpy(HCp,cd);/复制编码(串)b b 无 栈 非 递 归 遍 历 赫 夫 曼 树 ,求赫夫曼编码b else if (HTp.weight=1)/向右b HTp.weight=2;b if (HTp.rchild!=0)p=HTp.rchild; cdcdlen+=1;b else /HTp.weight=2,退回b HTp.weight=0

17、;p=HTp.parent;-cdlen;b /退到父结点,编码长度减1b /elseb/while例6-2 八种字符,其频率分别为:0.05,0.29,0.07,0.08,0.14,0.23,0.03,0.110.05,0.29,0.07,0.08,0.14,0.23,0.03,0.11HT.weight parent lchild rchild 1 2 3 4 5 6 7 8 9101112131415HT.weight parent lchild rchild 1 2 3 4 5 6 7 8 9101112131415532311178291400000001111110 1 1 012

18、345678 1 01 1 1 01 1 1 1 1 1 00 00 1 1 10 1 0HC6.8 树的计数b 称二叉树T和T相似是指:二者都为空树或者二者均不为空树,且它们的左右子树分别相似.b 称二叉树T和T等价是指:二者不仅相似,而且所有对应结点上的数据元素均相同.b 对给定的二叉树,其先序遍历、中序遍历和后序遍历都是唯一的。反过来是否唯一呢?b 结论是任意两个遍历确定后,这棵二叉树也就唯一确定了。例6-5 已知结点的前序序列和中序序列,求整棵二叉树。bb前序序列:A B C D E F Gbb中序序列:C B E D A F GACBEDFGABCDEFGABCFDEG实验与习题理论习题 6.19, 6.20, 6.22, 6.23 6.26, 6.28, 6.29, 6.37实验算法题: 6.38

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 医学/心理学 > 基础医学

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号