数据结构-树专题
树是数据结构当中一个很重要的结构,树有关的定义很多,为了巩固记忆,用博客的方式,将树有关的重点记录下来。
树
- 度为m的树中,第i层上至多有 m i − 1 m^{i-1} mi−1个结点。(i>= 1)
- 高度为h的m叉数至多有 ( m h m^h mh-1) /(m-1)个结点。
- n个结点的m叉树的最小高度为 [ log \log log m ( n* ( m -1 ) + 1 ) ] 取整符。
非空二叉树的叶子结点数等于度为2的结点数加1,即为 n0 = n2 + 1
完全二叉树
-
叶子结点只在最下两层。
-
若有度为1的结点,则只可能只有一个,且该结点只有左孩子,而没有右孩子。
-
n为奇数,每个分支结点都有左孩子和右孩子。
n为偶数,编号最大的分支结点 ( n/2 ) 只有左孩子,没有右孩子。
二叉排序树
- 左子树上的所有结点的关键字均小于根结点的关键字。
- 右子树上的所有结点的关键字均大于根节点的关键字。
- 左右子树又是一颗二叉排序树。
平衡二叉树
树上任一结点的左子树和右子树的深度之差不超过1。
二叉树
- 非空二叉树上的叶子结点数等于度为2的结点数加1
- 非空二叉树上的第k层上至多有2^(k-1)个结点 (k>=1)
- 高度为h的二叉树至多有 2^h -1 个结点
- 完全二叉树,结点i所在层次(深度)为 [ l o g 2 log2 log2 i ] + 1
- 具有n个结点的完全二叉树的高度为 [ l o g 2 log2 log2 ( n+1 ) ] 或者 [ l o g 2 log2 log2 n ] + 1
二叉树的存储结构
-
顺序存储结构
-
链式存储结构
完全二叉树和满二叉树采用顺序存储比较合适
这样最大可能节省存储空间,又能利用数组元素的下标值确定结点在二叉树中的位置,以及结点之间的关系。
引申:关于顺序存储结构的优点,可以通过数组 本身来体现?
在程序设计中,一个合理的数据结构会帮助我们更好地处理数据之间的关系。链式存储节省空间,但是由于链表本身的限制,不可以直接访问。
但数组本身可根据其计算公式,来计算得到任意结点的位置。可见,当选定一个结构时,可以通过相应的数学运算,通过结构本身的逻辑关系,来结合的解决问题。
树、森林
树有多种存储结构,可采用顺序存储结构,也可以采用链式存储结构。无论哪种方式,都要求唯一地反映各结点之间的逻辑关系。
-
双亲表示法
顺序表存储每个结点,多一个parent 数据项。typedef struct{ int data; int parent; }PTNode; typedef struct{ PTNode nodes [MAX_SIZE]; }PTree;
在树的顺序存储结构中,数组下标代表结点的编号,下标中所存的内容指示了结点见的关系。
在二叉树的顺序存储结构中,数组既代表结点的编号,有指示了二叉树中各结点见的关系。 -
孩子表示法
顺序表存储每个结点,用链表表示每个结点的孩子。
-
孩子兄弟表示法
struct Node{ int data; struct Node* firstchild, *nextbother; //第一个孩子和右兄弟指针 };
这种方法使得树转换成二叉树更方便,也易于查找结点的孩子。