一、基本概念
度:结点拥有的子树数目。
树的度:各结点度的最大值。
树的深度(高度):树中结点的最大层次(根为第一层)
二、树的存储结构
顺序存储:双亲表示法
链式存储:1.孩子表示法
2.孩子兄弟表示法(第一个孩子、右兄弟)
三、二叉树
1.二叉树的性质
(1)第i层最多2^(i-1)个结点
(2)深度为k的二叉树最多2^k-1个结点
(3)叶子结点数=度为2的结点树+1
(4)n个结点的完全二叉树的深度为不大于logn+1
(5)结点按层序对照满二叉树编号:
结点i=1,则结点为根,i>1则双亲为不大于i/2;
2i>n则i无左孩子,否则左孩子是2i;
2i+1>n则i无右孩子,否则右孩子为2i+1
2.分类
斜树:所有结点都只有左子树(左斜树)或右子树(右斜树)。
满二叉树:所有结点都有左右子树,并且叶子结点都在同一层。
完全二叉树:结点按层序对照满二叉树编号连续。
3.存储
顺序存储:一般只用于完全二叉树
链表存储:
二叉链表:一个数据域+两个指针域
三叉链表:数据域+三个指针域(左、右孩子、双亲)
4.树的遍历
前序、中序、后序、层序
1: template<class T>2: TreeNode<T> * Tree<T>::SearchParent(TreeNode<T> * &root, TreeNode<T> * &s)3: {4: if(root == NULL)
5: return NULL;
6: if(root->FirstChild() == s || root->NextSibling() == s)
7: return root;
8: TreeNode<T> * ptr;9: if((ptr = SearchParent(root->FirstChild(),s)) != NULL)
10: return ptr;
11: if((ptr = SearchParent(root->NextSibling(),s)) != NULL)
12: return ptr;
13: return NULL;
14: }15:16: template<class T>17: void Tree<T>::PreOrderTree(TreeNode<T> * &t)
18: {19: if(t == NULL)
20: return;
21: cout<<t->data<<" ";
22: if(t->firstChild != NULL)
23: PreOrderTree(t->firstChild);24: if(t->nextSibling != NULL)
25: PreOrderTree(t->nextSibling);26: }27:28: template<class T>29: void Tree<T>::MidOrderTree(TreeNode<T> * &t)
30: {31: if(t==NULL)
32: return;
33: if(t->firstChild != NULL)
34: PostOrderTree(t->firstChild);35: cout<<t->data<<" ";
36: if(t->nextSibling != NULL)
37: PostOrderTree(t->nextSibling);38: }39:40: template<class T>41: void Tree<T>::PostOrderTree(TreeNode<T> * &t)
42: {43: if(t==NULL)
44: return;
45: if(t->firstChild != NULL)
46: PostOrderTree(t->firstChild);47: if(t->nextSibling != NULL)
48: PostOrderTree(t->nextSibling);49: cout<<t->data<<" ";
50: }
5.树的转换
1: 树->二叉树2: step1:加线。兄弟结点间加线。3: step2:减线。只保留结点与第一个孩子的连线。4: step3:旋转。5: 森林->二叉树6: step1:每棵树都转化为二叉树。7: step2:后一棵树作为前一棵树的右孩子。8: 二叉树->树9: step1:加线。连接结点与结点左孩子的右孩子(以及右孩子的右孩子)。10: step2:减线。删去结点与右孩子的连线。11: step3:旋转。12: 二叉树->森林13: step1:从根结点开始删除与右孩子的连线,形成n个独立的二叉树。14: step2:将各个二叉树转换为树。15:
6 树的概念与分类
二叉树
非二叉树
空间数据分区树
其他树