树 - 二叉树

读了Robert Sedgewick的《算法:C语言实现》(第三版)的第五章,了解了许多关于树,特别是二叉树的知识。这里总结一下。直接看代码(C++)吧。

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <queue>
  4 #include <stack>
  5
  6 #define null 0
  7 #define NEXTLINE printf("\n")
  8 #define MAX(x, y) ((x)>(y)?(x):(y))
  9
 10 int max = 1<<31;
 11 int min = ~(1<<31);
 12
 13 typedef int Item;
 14 typedef struct node *link;
 15 struct node {
 16     Item item;
 17     link l, r;
 18 };
 19 // 初始化树
 20 link
 21 InitTree(Item item)
 22 {
 23     link t = (link)malloc(sizeof *t);
 24     if (t == null) {
 25         return null;
 26     }
 27     t->item = item;
 28     t->l = null;
 29     t->r = null;
 30     return t;
 31 }
 32 // 加入左子节点
 33 link
 34 AddLeftNode(link t, Item item)
 35 {
 36     if (t == null) {
 37         return null;
 38     }
 39     link newNode = (link)malloc(sizeof *newNode);
 40     if (newNode == null) {
 41         return null;
 42     }
 43     t->l = newNode;
 44     newNode->item = item;
 45     newNode->l = null;
 46     newNode->r = null;
 47     return newNode;
 48 }
 49 // 加入右子节点
 50 link
 51 AddRightNode(link t, Item item)
 52 {
 53     if (t == null) {
 54         return null;
 55     }
 56     link newNode = (link)malloc(sizeof *newNode);
 57     if (newNode == null) {
 58         return null;
 59     }
 60     t->r = newNode;
 61     newNode->item = item;
 62     newNode->l = null;
 63     newNode->r = null;
 64     return newNode;
 65 }
 66 // 打印节点中的内容
 67 void
 68 PrintItem(link t)
 69 {
 70     printf("%d\t", t->item);
 71 }
 72 // 前序遍历(递归)
 73 void
 74 PreTraverse(link t)
 75 {
 76     if (t == null) {
 77         return;
 78     }
 79     PrintItem(t);
 80     PreTraverse(t->l);
 81     PreTraverse(t->r);
 82 }
 83 // 中序遍历(递归)
 84 void
 85 InTraverse(link t)
 86 {
 87     if (t == null) {
 88         return;
 89     }
 90     InTraverse(t->l);
 91     PrintItem(t);
 92     InTraverse(t->r);
 93 }
 94 // 后序遍历(递归)
 95 void
 96 PostTraverse(link t)
 97 {
 98     if (t == null) {
 99         return;
100     }
101     PostTraverse(t->l);
102     PostTraverse(t->r);
103     PrintItem(t);
104 }
105 // 层次遍历(非递归)
106 void
107 LevelTraverse(link t)
108 {
109     if (t == null) {
110         return;
111     }
112     std::queue<link> linkQueue;
113     linkQueue.push(t);
114     while (!linkQueue.empty()) {
115         PrintItem(t = linkQueue.front());
116         linkQueue.pop();
117         if (t->l != null) linkQueue.push(t->l);
118         if (t->r != null) linkQueue.push(t->r);
119     }
120 }
121 // 前序遍历(非递归)
122 void
123 PreTraverseNR(link t)
124 {
125     if (t == null) {
126         return;
127     }
128     std::stack<link> linkStack;
129     linkStack.push(t);
130     while (!linkStack.empty()) {
131         PrintItem(t = linkStack.top());
132         linkStack.pop();
133         if (t->r != null) linkStack.push(t->r);
134         if (t->l != null) linkStack.push(t->l);
135     }
136 }
137 // 找最大节点
138 void
139 FindMax(link t)
140 {
141     if (t == null) {
142         return;
143     }
144     if (max < t->item) {
145         max = t->item;
146     }
147     FindMax(t->l);
148     FindMax(t->r);
149 }
150 // 找最小节点
151 void
152 FindMin(link t)
153 {
154     if (t == null) {
155         return;
156     }
157     if (min > t->item) {
158         min = t->item;
159     }
160     FindMin(t->l);
161     FindMin(t->r);
162 }
163 // 计算深度(从0开始计算)
164 int
165 CountDepth(link t)
166 {
167     if (t == null) {
168         return -1;
169     }
170     return MAX(CountDepth(t->l), CountDepth(t->r)) + 1;
171 }
172 // 计算所有节点数目
173 int
174 CountNodes(link t)
175 {
176     if (t == null) {
177         return 0;
178     }
179     return CountNodes(t->l) + CountNodes(t->r) + 1;
180 }
181 // 计算叶子节点数目
182 int
183 CountLeaves(link t)
184 {
185     if (t == null) {
186         return 0;
187     }
188     if (!CountLeaves(t->l) && !CountLeaves(t->r)) {
189         return 1;
190     }
191     return CountLeaves(t->l) + CountLeaves(t->r);
192 }
193 // 清空一棵树
194 void
195 DeleteTree(link t)
196 {
197     if (t == null) {
198         return;
199     }
200     if (!(t->l) && !(t->r)) {
201         free(t);
202         return;
203     }
204     DeleteTree(t->l);
205     DeleteTree(t->r);
206     free(t);
207 }
208
209 int
210 main(int argc, char** argv)
211 {
212     link t, t1, t2, t3, t4;
213     t = InitTree(1);
214     t1 = AddLeftNode(t, 2);
215     t2 = AddRightNode(t, 3);
216     t3 = AddLeftNode(t1, 4);
217     t4 = AddRightNode(t1, 5);
218
219
220     PreTraverse(t);
221     NEXTLINE;
222     InTraverse(t);
223     NEXTLINE;
224     PostTraverse(t);
225     NEXTLINE;
226     LevelTraverse(t);
227     NEXTLINE;
228     PreTraverseNR(t);
229     NEXTLINE;
230
231     FindMax(t);
232     FindMin(t);
233     printf("Maxima Item in tree: %d\n", max);
234     printf("Minima Item in tree: %d\n", min);
235
236     printf("Depth of the tree(start from 0): %d\n", CountDepth(t));
237
238     printf("Number of the nodes of the tree: %d\n", CountNodes(t));
239
240     printf("Number of the leaves of the tree: %d\n", CountLeaves(t));
241
242
243     DeleteTree(t);
244
245     system("pause");
246     return 0;
247 }
时间: 2024-10-08 11:13:04

树 - 二叉树的相关文章

纸上谈兵: 树, 二叉树, 二叉搜索树

树的特征和定义 树(Tree)是元素的集合.我们先以比较直观的方式介绍树.下面的数据结构是一个树: 树有多个节点(node),用以储存元素.某些节点之间存在一定的关系,用连线表示,连线称为边(edge).边的上端节点称为父节点,下端称为子节点.树像是一个不断分叉的树根. 每个节点可以有多个子节点(children),而该节点是相应子节点的父节点(parent).比如说,3,5是6的子节点,6是3,5的父节点:1,8,7是3的子节点, 3是1,8,7的父节点.树有一个没有父节点的节点,称为根节点(

树——二叉树的线索化

1,什么是线索化二叉树? 1,将二叉树转换为双向链表的过程(非线性 ==> 线性): 1,实际工程开发中,很大一部分情况下,二叉树一旦建立之后,就不会轻易改动,一般的用于遍历,并且这种操作一般执行很多: 2,先中后序遍历都是递归完成的,实际工程开发中,对一棵已经建立的二叉树反复执行先序遍历,效率低,所以不推荐反复的递归的遍历: 3,直接将遍历后的结果保存下来,下一次遍历直接用这个结果就可以: 4,工程开发中还有一种常见情况,就是要反复的知道某个结点在中序遍历下,前驱结点是谁.后继结点是谁,需要这

树——二叉树的先序、中序和后序遍历

1,二叉树是否只有一种遍历方式(层次遍历)? 2,典型的二叉树的遍历方式: 1,先序遍历(Pre-Order Traversal): 2,中序遍历(In-Order Traversal): 3,后序遍历(Post-Order Traversal): 3,先序遍历(“先序”指最先访问根结点中的数据元素): 1,二叉树为空: 1,无操作,直接返回: 2,二叉树不为空: 1,访问根结点中的数据元素: 2,先序遍历左子树: 3,先序遍历右子树: 4,先序遍历功能定义及其代码实现: 1,代码示例: 1 p

树&amp;二叉树

(哈弗曼树.哈弗曼编码.排序二叉树.平衡二叉树.红黑树.3种遍历(先序,后序,中序).深度-广度优先遍历) 关键词.语句: 树的三种存储结构:父节点表示法.子节点表示法.链表存储 树代表一种非线性的数据结构 如果一组数组节点之间存在复杂的一对多关联时,程序就可以考虑使用树来保存这组数据了 一对多?例如,一个父节点可以包含多个子节点 TreeMap即利用红黑树实现 树:一个集合(里面存在N个有父子关系的节点,N有限,即有限集合) 满足条件(请背诵下来): a.  当N=0的时候,节点集合为空,称为

树 二叉树 森林 之间转换

树.森林和二叉树之间的转换 树转换为二叉树 1. 加线 在所有兄弟结点之间加一条连线. 2. 去线 树中的每个结点,只保留它与第一个孩子结点的连线,删除它与其它孩子结点之间的连线. 3. 层次调整 以树的根节点为轴心,将整棵树顺时针旋转一定角度,使之结构层次分明.(注意第一个孩子是结点的左孩子,兄弟转换过来的孩子是结点的右孩子) 森林转换为二叉树 1. 把每棵树转换为二叉树. 2. 第一棵二叉树不动,从第二棵二叉树开始,依次把后一棵二叉树的根结点作为前一棵二叉树的根结点的右孩子,用线连接起来.

数据结构与算法-----&gt;数据结构-----&gt;树-------&gt;二叉树的遍历

二叉树的遍历 第一部分 基本概念以及编程实现 概述: 遍历树,就是指按照一定的顺序访问树中的所有节点. 遍历树有三种常用方法,分别是中序遍历(inorder).前序遍历(preorder).后序遍历(postorder) 三种遍历方法的三个步骤都是相同的,只不过这三个步骤的执行顺序不同.三种遍历方式的名称的由来是根据""访问节点内容""这个步骤的执行时间来定的,这个步骤在第一步执行的是前序遍历,在第二步执行的是中序遍历,在第三步执行的是后序遍历. 1.1中序遍历(i

数据结构学习笔记04树(二叉树、二叉搜索树、平衡二叉树)

一.树 树的基本术语 ①结点的度(Degree):结点的子树个数 ②树的度:树的所有结点中最大的度数 ③叶结点(Leaf):度为0的结点 ④父结点(Parent):有子树的结点是其子树的根结点的父结点 ⑤子结点(Child):若A结点是B结点的父结点,则称B结点是A结点的子结点:子结点也称孩子结点. ⑥兄弟结点(Sibling):具有同一父结点的各结点彼此是兄弟结点. ⑦路径和路径长度:从结点n1到nk的路径为一个结点序列n1 , n2 ,… , nk , ni是 ni+1的父结点.路径所包含边

树 二叉树 多叉树

本文先介绍了树的概念,然后给出了二叉树和多叉树的实现源码实例. 一.树的概念 树(本质上就使用了递归来定义的,递归就是堆栈应用,因此树离不开递归和堆栈):树是n个点的有限结合.n=0时是空树,n=1时有且仅有一个结点叫做根,n>1,其余的结点被分成m个互不相交的子集,每一个子集又是一棵树. 森林 二叉树 满二叉树 深度为k,结点个数是2的k次方-1的二叉树. 完全二叉树 深度为k,结点为n,当且仅当每一个结点的编号与对应的满二叉树完全一致. 顺序存储:访问方便 链式存储:删除方便 二叉排序树:对

树, 二叉树, 二叉搜索树

转载:Vamei   出处:http://www.cnblogs.com/vamei 树的特征和定义 树(Tree)是元素的集合.我们先以比较直观的方式介绍树.下面的数据结构是一个树: 树有多个节点(node),用以储存元素.某些节点之间存在一定的关系,用连线表示,连线称为边(edge).边的上端节点称为父节点,下端称为子节点.树像是一个不断分叉的树根. 每个节点可以有多个子节点(children),而该节点是相应子节点的父节点(parent).比如说,3,5是6的子节点,6是3,5的父节点:1