[关闭]
@yanglt7 2018-10-21T15:50:02.000000Z 字数 6736 阅读 763

08_树

数据结构和算法


8.1 树

8.1.1 树的定义

Tips:

8.1.2 结点分类

8.1.3 结点间的关系

8.1.4 结点的层次

8.2 树的存储结构

8.2.1 双亲表示法

  1. //树的双亲表示法结点结构定义
  2. #define MAX_TREE_SIZE 100
  3. typedef int ElemType;
  4. typedef struct PTNode
  5. {
  6. ElemType data; //结点数据
  7. int parent; //双亲位置
  8. }PTNode
  9. typedef struct
  10. {
  11. PTNode nodes[MAX_TREE_SIZE];
  12. int r; //根的位置
  13. int n; //结点数目
  14. }PTree;

8.2.2 孩子双亲表示法

  1. #define MAX_TREE_SIZE 100
  2. typedef char ElemType;
  3. //孩子结点
  4. typedef struct CTNode
  5. {
  6. int child; //孩子结点的下标
  7. struct CTNode *next; //指向下一个孩子结点的指针
  8. } *ChildPtr;
  9. //表头结构
  10. typedef struct
  11. {
  12. ElemType data; //存放在树中的结点的数据
  13. int parent; //存放双亲的下标
  14. ChildPtr firstchild; //指向第一个孩子的指针
  15. } CTBox;
  16. //树结构
  17. typedef struct
  18. {
  19. CTBox nodes[MAX_TREE_SIZE]; //结点数组
  20. int r,n;
  21. };

8.3 二叉树

8.3.1 二叉树定义

8.3.2 二叉树的特点

8.3.3 二叉树的五种基本形态

8.3.4 特殊二叉树

8.3.5 二叉树的性质

性质一

性质二

性质三

性质四

性质五

8.4 二叉树的存储结构

8.4.1 二叉树的顺序存储结构

元素 A B C D E F ^
下标 1 2 3 4 5 6 7

8.4.2 二叉链表

lchild data rchild

- 结构定义代码

  1. typedef struct BiTNode
  2. {
  3. ElemType data;
  4. struct BiTNode *lchild, *rchild
  5. } BiTNode, *BiTree;

8.5 二叉树的遍历

8.5.1 二叉树的遍历方法

前序遍历

中序遍历

后序遍历

层序遍历

8.5.2 二叉树的建立和遍历算法

  1. //前序遍历
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. typedef char ElemType;
  5. typedef struct BiTNode
  6. {
  7. char data;
  8. struct BiTNode *lchild, *rchild;
  9. } BiTNode, *BiTree;
  10. //创建一棵二叉树,约定用户遵照前序遍历的方式输入数据
  11. CreateBiTree(BiTree *T)
  12. {
  13. char c;
  14. scanf("%c", &c);
  15. if( ' ' == c )
  16. {
  17. *T = NULL;
  18. }
  19. else
  20. {
  21. *T = (BiTNode *)malloc(sizeof(BiTNode));
  22. (*T)->data = c;
  23. CreateBiTree(&(*T)->lchild);
  24. CreateBiTree(&(*T)->rchild);
  25. }
  26. }
  27. //访问二叉树结点的具体操作
  28. visit(char c, int level)
  29. {
  30. printf("%c 位于第 %d 层\n", c, level);
  31. }
  32. //前序遍历二叉树
  33. PreOrderTraverse(BiTree T, int level)
  34. {
  35. if( T )
  36. {
  37. visit(T->data, level);
  38. PreOrderTraverse(T->lchild, level+1);
  39. PreOrderTraverse(T->rchild, level+1);
  40. }
  41. }
  42. int main()
  43. {
  44. int level = 1;
  45. BiTree T = NULL;
  46. CreateBiTree(&T);
  47. PreOrderTraverse(T, level);
  48. return 0;
  49. }

8.6 线索二叉树

lchild ltag data rtag rchild

- ltag为0时指向该结点的左孩子,为1时指向该结点的前驱
- rtag为0时指向该结点的右孩子,为1时指向该结点的后继

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef char ElemType;
  4. //线索存储标志位
  5. //Link(0):表示指向左右孩子的指针
  6. //Thread(1):表示指向前驱后继的线索
  7. typedef enum {Link, Thread} PointerTag;
  8. typedef struct BiThrNode
  9. {
  10. char data;
  11. struct BiThrNode *lchild, *rchild;
  12. PointerTag ltag;
  13. PointerTag rtag;
  14. } BiThrNode, *BiThrTree;
  15. //全局变量,始终指向刚刚访问过的结点
  16. BiThrTree pre;
  17. //创建一棵二叉树,约定用户遵照前序遍历的方式输入数据
  18. void CreateBiThrTree(BiThrTree *T)
  19. {
  20. char c;
  21. scanf("%c", &c);
  22. if( ' ' == c )
  23. {
  24. *T = NULL;
  25. }
  26. else
  27. {
  28. *T = (BiThrNode *)malloc(sizeof(BiThrNode));
  29. (*T)->data = c;
  30. (*T)->ltag = Link;
  31. (*T)->rtag = Link;
  32. CreateBiThrTree(&(*T)->lchild);
  33. CreateBiThrTree(&(*T)->rchild);
  34. }
  35. }
  36. //中序遍历线索化
  37. void InThreading(BiThrTree T)
  38. {
  39. if( T )
  40. {
  41. InThreading( T->lchild ); //递归左孩子线索化
  42. //结点处理
  43. //如果该结点没有左孩子,设置ltag为Thread,并把lchild指向刚刚访问的结点
  44. if( !T->lchild )
  45. {
  46. T->ltag = Thread;
  47. T->lchild = pre;
  48. }
  49. if( !pre->rchild )
  50. {
  51. pre->rtag = Thread;
  52. pre->rchild = T;
  53. }
  54. pre = T;
  55. InThreading( T->rchild ); //递归右孩子线索化
  56. }
  57. }
  58. void InOrderThreading( BiThrTree *p, BiThrTree T )
  59. {
  60. *p = (BiThrTree)malloc(sizeof(BiThrNode));
  61. (*p)->ltag = Link;
  62. (*p)->rtag = Thread;
  63. (*p)->rchild = *p;
  64. if( !T )
  65. {
  66. (*p)->lchild = *p;
  67. }
  68. else
  69. {
  70. (*p)->lchild = T;
  71. pre = *p;
  72. InThreading( T );
  73. pre->rchild = *p;
  74. pre->rtag = Thread;
  75. (*p)->rchild = pre;
  76. }
  77. }
  78. void visit( char c )
  79. {
  80. printf("%c", c );
  81. }
  82. //中序遍历二叉树,非递归
  83. void InOrderTraverse( BiThrTree T )
  84. {
  85. BiThrTree p;
  86. p = T->lchild;
  87. while( p != T )
  88. {
  89. while( p->ltag == Link )
  90. {
  91. p = p->lchild;
  92. }
  93. visit( p->data );
  94. while( p->rtag == Thread && p->rchild != T )
  95. {
  96. p = p->rchild;
  97. visit(p->data);
  98. }
  99. p = p->rchild;
  100. }
  101. }
  102. int main()
  103. {
  104. BiThrTree P, T = NULL;
  105. CreateBiThrTree( &T );
  106. InOrderThreading( &P, T );
  107. printf("中序遍历输出结果为: \n");
  108. InOrderTraverse( P );
  109. return 0;
  110. }

8.7 树、森林及二叉树的相互转换

8.7.1 树到二叉树的转换

8.7.2 森林转换为二叉树

8.7.3 二叉树到树、森林的转换

8.8 树与森林的遍历

8.8.1 树的遍历

8.8.2 森林的遍历

8.9 赫夫曼树

8.9.1 赫夫曼树定义与原理

8.9.2 构造赫夫曼树过程

8.10 赫夫曼编码

8.10.1 名词解释

定长编码

变长编码

前缀码

8.10.2 思路

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注