1 / 43

6.3 遍历二叉树和线索二叉树 6.3.1 遍历二叉树 6.3.2 建立(生成)二叉树 6.3.3 线索二叉树 6.3.4 表达式二叉树

6.3 遍历二叉树和线索二叉树 6.3.1 遍历二叉树 6.3.2 建立(生成)二叉树 6.3.3 线索二叉树 6.3.4 表达式二叉树 表达式二叉树 T = ( 第一操作数) (运算符) (第二操作数) 其中:第一操作数、第二操作数也是表达式二叉树, 分别为表达式二叉树 T 的左子树和右子树. 运算符. 第一操作数 左二叉树. 第二操作数 右二叉树. 表达式二叉树. 例 表达式: A + B * C - D /(E - F). -. +. /. A. *. D. -. B. C. E. F. 表达式二叉树.

katoka
Télécharger la présentation

6.3 遍历二叉树和线索二叉树 6.3.1 遍历二叉树 6.3.2 建立(生成)二叉树 6.3.3 线索二叉树 6.3.4 表达式二叉树

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 6.3 遍历二叉树和线索二叉树 • 6.3.1 遍历二叉树 • 6.3.2 建立(生成)二叉树 • 6.3.3 线索二叉树 • 6.3.4 表达式二叉树 • 表达式二叉树T = (第一操作数) (运算符) (第二操作数) • 其中:第一操作数、第二操作数也是表达式二叉树, • 分别为表达式二叉树T的左子树和右子树 运算符 第一操作数 左二叉树 第二操作数 右二叉树 表达式二叉树

  2. 例 表达式: A + B * C - D /(E - F) - + / A * D - B C E F 表达式二叉树 ●前序遍历:- + A * B C / D - E F 前缀表示,前缀表达式,波兰式 ●中序遍历: A + B * C - D /( E - F ) 中缀表示,中缀表达式 ●后序遍历: A B C * + D E F - / - 后缀表示,后缀表达式,逆波兰式

  3. 6.3.5 中序遍历序列和前(或后)序序列确定唯一棵二叉树 由前序序列:A D E B C 和(或)后序序列:E D C B A 不能确定唯一棵二叉树(如图T1,T2) A A D B D B E C E C T1 T2 例1. 给定二叉树T的 中序序列:B A C D E G F 前序序列:E A B C DF G 如何求二叉树T? E A F E B C G B,A,C,D G,F D

  4. 6.3.5 中序遍历序列和前(或后)序序列确定唯一棵二叉树 例2. 给定二叉树T的 后序序列:B G H E C AJ I F D 中序序列:B A C G E H D I J F 如何求二叉树T?(根结点,左右子树结点) D B,A,C G,E,H I,J,F

  5. 6.3.5 中序遍历序列和前(或后)序序列确定唯一棵二叉树 例2. 给定二叉树T的 后序序列:B G H E C AJ I F D 中序序列:B A C G E H D I J F 如何求二叉树T? D A F D B C I B,A,C G,E,H I,J,F E J G H 二叉树T

  6. 递归算法 • 1.前序遍历以root为根指针的二叉树 • preorder(struct nodeb *root) • { if (root) //为非空二叉树 • { printf("%c",root->data); //访问根结点 • preorder(root->lchild); //递归遍历左子树 • preorder(root->rchild); //递归遍历右子树 • } • } 6.3.6 遍历二叉树算法 root A B C D E F 二叉树 二叉链表

  7. 执行preorder(struct nodeb *t); 地址栈 根指针栈 t t1 1.输出A;L1,t进栈 t2 2.t指向B,记作t1;输出B; L1,t1进栈 preorder(struct nodeb *t) { if (t) { printf("%c",t->data); preorder(t->lchild); L1: preorder(t->rchild); L2:} } 3.t指向NULL,记作t2;退栈,返回到L1,恢复t1;L2,t1进栈

  8. 执行preorder(struct nodeb *t); t t1 t2 t3 4.t指向D,记作t3;输出D; L1、t3进栈 t4 preorder(struct nodeb *t) { if (t) { printf("%c",t->data); preorder(t->lchild); L1: preorder(t->rchild); L2:} } 5.t指向E,记作t4; 输出E;L1,t4进栈

  9. 执行preorder(struct nodeb *t); t t1 6.t指向NULL,记作t5; 退栈,返回到L1,恢复t4; L2、t4进栈 t3 t4 t5 t6 preorder(struct nodeb *t) { if (t) { printf("%c",t->data); preorder(t->lchild); L1: preorder(t->rchild); L2:} } 7.t指向NULL,记作t6; 退栈,返回到L2,恢复t4; 退栈,返回到L1,恢复t3; L2、t3进栈

  10. 执行preorder(struct nodeb *t); t t1 t3 8.t指向F,记作t7; 输出F;L1,t7进栈 t7 t8 preorder(struct nodeb *t) { if (t) { printf("%c",t->data); preorder(t->lchild); L1: preorder(t->rchild); L2:} } 9.t指向NULL,记作t8; 退栈,返回到L1,恢复t7; L2,t7进栈

  11. 执行preorder(struct nodeb *t); t t1 10.t指向NULL,记作t9; 退栈,返回到L2,恢复t7; 退栈,返回到L2,恢复t3; t3 t7 t9 preorder(struct nodeb *t) { if (t) { printf("%c",t->data); preorder(t->lchild); L1: preorder(t->rchild); L2:} } 退栈,返回到L2,恢复t1; 退栈,返回到L1,恢复t; L2、t进栈

  12. 执行preorder(struct nodeb *t); t t10 t11 11.t指向C,记作t10; 输出C;L1,t10进栈 preorder(struct nodeb *t) { if (t) { printf("%c",t->data); preorder(t->lchild); L1: preorder(t->rchild); L2:} } 12.t指向NULL,记作t11; 退栈,返回到L1,恢复t10; L2、t10进栈

  13. 执行preorder(struct nodeb *t); t t10 t12 13.t指向NUII,记作t12; 退栈,返回到L2,恢复t10 preorder(struct nodeb *t) { if (t) { printf("%c",t->data); preorder(t->lchild); L1: preorder(t->rchild); L2:} } 退栈,返回到L2,恢复t; preorder(struct nodeb *t) 执行结束。

  14. 2.中序遍历以root为根指针的二叉树 t A B C D E F 二叉树 二叉链表 preorder(struct nodeb *root) //递归算法 { if (root) //为非空二叉树 { preorder(root->lchild); //递归遍历左子树 printf("%c",root->data); //访问根结点,字符型 preorder(root->rchild); //递归遍历右子树 } }

  15. 3.后序遍历以root为根指针的二叉树 t A B C D E F 二叉树 二叉链表 preorder(struct nodeb *root) //递归算法 { if (root) //为非空二叉树 { preorder(root->lchild); //递归遍历左子树 preorder(root->rchild); //递归遍历右子树 printf("%c",root->data); //访问根结点 } }

  16. 4.中序遍历非递归算法 • preorder(struct nodeb *t) //t为根指针 • { struct bnode *st[maxleng+1];//定义地址栈st[0..maxleng] • int top=0; //置空栈 • do • { while(t) //为非空二叉树 • { if (top==maxleng) exit("overflow");//栈已满,退出 • st[++top]=t; //根地址进栈 • t=t->lchild; //t移向左子树 • } • if (top) //为非空栈 • { t=st[top--]; //弹出根地址 • printf("%c",t->data); //访问根结点 • t=t->rchild; //遍历右子树 • } • } • while(top||t); • } //父结点未访问,或右子树未遍历

  17. 6.3.7 遍历二叉树的应用 • 例. 求二叉树中结点的个数 • creat_tree(struct bnode **root) //生成二叉树 • { ........... • } • preorder(struct nodeb *root,int *n)//求二叉树中结点的个数 • { if (root) • { (*n)++; //计数 • preorder(root->lchild,n); //递归遍历左子树 • preorder(root->rchild,n); //递归遍历右子树 • } • } • main() • { int n=0; //n为计数器,假定二叉树已生成 • preorder(root,&n); //root为指针,执行preorder(root,&n) • printf("%d",n); //输出n • }

  18. 6.4 树和森林 • 6.4.1 树的存储结构 • 1.双亲表示法/数组表示法/顺序表示法 data parent A 1 2 3 4 5 6 7 B C D E F G 树 t[1..7] struct snode { char data; int parent; }t[maxleng+1};

  19. 2.孩子表示法/链接表表示法 • (1)固定大小的结点格式,(设树T的度为k,结点数为n) data child1 childk root A B C D E F G 树T T的链接表

  20. 2.孩子表示法/链接表表示法 2.孩子表示法/链接表表示法 (1)固定大小的结点格式,(设树T的度为k,结点数为n) 优点:各结点结构相同。 缺点:空域多达 n(k-1)+1 个。 练习:如T是一棵有 n 个结点的、度为 k 的树,每个 结点有k个指针域,则在nk个指针域中有n (k-1)+1 个指针为空域。 证:由于每个非空指针域指向一个结点,而且除根结点外的每一个结点都有一个指针指向,故在一棵n个结点的树中非空指针的个数恰好是n-1。 又因T中每一结点有k个指针域,故T中共有nk个域,因此,空域的个数为 nk-(n-1)=n(k-1)+1 证毕

  21. 2.孩子表示法/链接表表示法 • (2)非固定大小的结点格式 data degree child1 childn root A B C D E F G 树 链接表

  22. 3.孩子兄弟表示法/二叉树表示法/二叉链表 firstchild data nextbrother 右兄弟 左孩子 root A B C G D E F H I J K 树 二叉链表

  23. 3.孩子兄弟表示法/二叉树表示法/二叉链表 root firstchild data nextbrother 左孩子 右兄弟 A B C G D E F H I J K 树 二叉链表

  24. 4.孩子链表表示法/单链表表示法 data first child next 第一个孩子 下一个孩子 表头结点 孩子结点/表结点 1 2 3 4 5 6 7 8 9 10 11 A B C G D E F H I J K 树 表头结点数组

  25. 5.带双亲的孩子链表表示法 data parent first child next 第一个孩子 下一个孩子 表头结点 孩子结点/表结点 1 2 3 4 5 6 7 8 9 10 11 A B C G D E F H I J K 树 表头结点数组

  26. 6.4.2 树与二叉树的转换 • 1.树 二叉树 A A B C B C D E F G H E D F G H I J K L M J K L M I 树 1.在兄弟之间加连线 A B C D E F G H I J K L M 2.保留根与最左孩之间的连线 删除与其它孩子之间的连线

  27. 1.树 二叉树 A B A D C B C I E F D E F G H J K G I J K L M H 2.保留根与最左孩之间的连线 删除与其它孩子之间的连线 L M 二叉树 3.以根为轴心顺时针 方向旋转45度

  28. 2.森林 二叉树 G J A F G J A F H I B C D H I K K B C D L M E L M E T2 T3 T1 T4 加线拆线之后 A F G J A F G J B H K B H K C I L C I L E D M E D M B2 B3 B2 B3 B1 BT4 B1 BT4 旋转后变为多棵二叉树 连成一棵二叉树

  29. 2.森林 二叉树 A A F G J B F C G B C D H I K E D H J E L M T2 T3 T1 T4 I K 森林F={T1,T2,T3,T4} L M 旋转后,变为一棵二叉树

  30. 3. 二叉树 树 A 例1 A B B C D C D E F G E F G H I J H I J 二叉树B A A B B D G C D C F I J E F G E H H I J 树T

  31. 3. 二叉树 森林 例2 A A B H B H C D I C D I E F G J K E F G J K 二叉树B A H I K A B H J B D G C D I C F E F G J K E T1 T2 T3 T4

  32. 6.4.3 树和森林的遍历 • 1.树的遍历 A 前根遍历:A B G H I C D E J K F 后根遍历:H I G B D J K E F C A B C G D E F H I J K 2.森林的遍历 前序遍历:A B C D E F G H I J K L 中序遍历:B D C A F E H J K I L G G A E B C F H I L D J K

  33. 6.6 哈夫曼(Huffman)树及其应用 • 1.路径长度----路径上分枝的数目(连线的数目) • 2.树T的路径长度----从树T的根到其余每个结点的路径长度之和 • 记作PL(T) PL(T1)=1+1+2+2+2=8 PL(T2)=1+2+3+4+5=15 PL(T3)=1+1+2+3+3=10 ● T1,T3各有3个叶子,但其PL值互不相同??? T1 T2 T3 ●当n个结点的二叉树为完全二叉树时,PL(T)具有最小值: ∵ 结点i的层 = log2i + 1 树T的根到结点i的路径长度 = 结点i的层-1 = log2i n ∴ PL(T)= log2i+log2i+...+log2i = ∑log2i i=1

  34. ●当n个结点的二叉树为单枝树时,PL(T)具有最大值:●当n个结点的二叉树为单枝树时,PL(T)具有最大值: • PL(T)=0+1+2+...+(n-1) = n(n-1)/2 • 3. 树T的带权路径长度----每个叶子的权与根到该叶子的路径 • 长度的乘积之和,记作WPL(T) • n • WPL(T) = ∑ wklk • i=1 • 其中: n ---树T的叶子数目 wk--- 叶子i的权 • lk--- 树T的根到叶子i的路径长度 7 WPL(T)=6*1+3*2+4*3+9*3=51 5 6 3 8 4 9 T1

  35. 4.哈夫曼树/最佳树/最优树---- • 在具有n个相同叶子的各二叉树中,WPL(T)最小的二叉树。 28 28 28 11 17 14 14 10 18 5 6 7 10 11 3 4 10 6 12 3 4 5 6 5 7 T1 T3 T2 4 3 ● PL(T1)=1+1+2+2+2+2+3+3=16 ● WPL(T1)=5*3+6*3+3*2+4*2+10*2=67 ● PL(T2)=1+1+2+2+3+3+4+4=20 ● WPL(T2)=10*1+6*2+5*3+4*4+3*4=65 ● PL(T3)=1+1+2+2++2+2+3+3=16 ● WPL(T3)=5*3+6*3+3*2+4*2+10*2=63

  36. 5.哈夫曼算法 • 例 给定权集合{4,5,3,6,10},构造哈夫曼树 • 1.按权值大小排序: 3,4,5,6,10 • 2.生成森林: 3 4 5 6 10 T1 T2 T3 T4 T5 3.合并两棵权最小的二叉树,并排序,直到为一棵二叉树: 5 6 7 10 7 10 11 3 4 3 4 5 6 28 11 17 11 17 5 6 7 10 5 6 7 10 3 4 3 4

  37. 6.最小冗余码/哈夫曼码 • ● ASCII码/定长码 • ab12: 01100001 01100010 00110001 00110010 • 97 98 49 50 • ●哈夫曼码/不定长码 • 能按字符的使用频度,使文本代码的总长度具有最小值。 • 例. 给定有18个字符组成的文本: • A A D A T A R A E F R T A A F T E R • 求各字符的哈夫曼码。 • (1) 统计: (2) 构造Huffman树: 1 2 2 3 3 7

  38. (2) 构造Huffman树: 3 2 3 3 3 7 1 2 2 3 3 7 1 2 合并1和2 排序 5 3 3 5 7 2 3 3 3 7 2 3 1 2 1 2 排序 合并2和3

  39. (2) 构造Huffman树: 6 5 6 7 3 3 5 7 3 3 2 3 2 3 1 2 排序 1 2 合并3和3 7 11 11 5 6 5 6 7 3 3 3 3 2 3 2 3 1 2 1 2 合并5和6 排序

  40. (2) 构造Huffman树: (3) 在左分枝标0,右分枝标1: 18 18 0 1 7 11 7 11 1 0 A 5 6 5 6 0 1 0 1 3 3 3 3 2 3 2 3 0 1 F T R 1 2 1 2 D E 合并7和11 Huffman树 (4) 确定Huffman编码: 特点:任一编码不是其它编码的前缀

  41. 如何译码? 18 0 1 7 11 1 0 A 5 6 0 1 0 1 3 3 2 3 0 1 F T R 1 2 D E Huffman树 例. 给定代码序列: 0 0 1 0 0 0 1 1 1 0 1 0 1 0 1 0 1 1 1 10 文本为:A A F A R A D E T

  42. 一、填空 • 1.假设含有20个元素的线性表顺序存储, 欲在它的第11和 • 第12个元素之间插入一个新元素, 共需移动 ______元素。 • 2.设数组A[1..6, 1..8 ]的基地址为1000,每个元素占2 • 个存储单元,若以行序为主序顺序存储, 则元素A[4,5]的存储 • 地址为 _________ 。 • 3. 一棵深度为5的二叉树最多有 ___________ 个结点。 • 4.具有n个结点的二叉树的二叉链表共有 ________ 个空 • 链域和______个非空链域 。 • 5.具有n个结点的满二叉树共有_____________个叶结 • 点和___________个非叶结点。 • 6.若一棵二叉树中有10个度为2的结点,则它有 _______ • 个叶子。 • 二、回答问题:二叉树有哪几种基本形态? 画图说明之。

  43. 三、给定21个字符组成的文本(电文): • A A A B B B A A A A B B B C C A C C D D E, • 试为字符 A、B、C、D、E 设计哈夫曼(Huffman)编码。 • 1.画出相应的哈夫曼树; • 2.分别列出 A、B、C、D、E、F 的哈夫曼码 四、画图 1.画出数组 A[2][3] 的以行序 为主序的顺序存储结构。 2.依次将元素D,C,A,B,E插入一 个初始状态为空的链式栈中,试画出 插入完成之后的链式栈。 3.画出右面二叉树的先序线索二 叉树、中序线索二叉树、后序线索二 叉树。 A B H C D I F J K G E 二叉树

More Related