树与二叉树
一、树
树的定义是递归的,即在树的定义中又用到了其自身,树是一种递归的数据结构。树作为一种逻辑结构,同时也是一种分层结构,结点间关系是前驱唯一而后继不唯一,即结点之间是一对多的关系。
树中结点的最大度数就是树的度;树中一个结点的孩子个数称为该结点的度
n个结点的树中有n-1条边 ;结点数=总度数+1
度为m的树中第i层上至多有mi-1结点(i>.=1)
高度为h的m叉树至多有(mh-1)/(m-1)个结点
二、二叉树
(1)每个结点的度不大于2(2)每个结点的孩子结点次序不能任意颠倒
一个二叉树中的每个结点只能含有0个,1个,2个孩子,并且每个孩子有左右孩子之分.
二叉树的五种形态:(1)空二叉树(2)只有根结点的二叉树(3)只有左子树的二叉树(4)只有右子树的二叉树(5)左右子树非空的二叉树
二叉树是有序的树,若将其左右子树颠倒,则成为另一棵不同的二叉树,它的左右子树是确定的,而树若某个结点只有一个孩子,则这个孩子无须分次序。
满二叉树:除了叶子结点外每个结点的度都为2 编号为i的结点:双亲i/2向下取整,左孩子:2i 右孩子:2i+1
完全二叉树:当且仅当每个结点都与高度为h的满二叉树中编号1-n的结点一一对应时,称为完全二叉树
对于完全二叉树:i<=n/2向下取整,则结点i为分支结点,否则为叶子结点
二叉排序树:右>根>左
平衡二叉树:树中任一结点的左子树和右子树的深度之差不超过1
二叉树的性质:
n0=n2+1;n=n0+n1+n2=n2+1+n1+n2=2n2+n1+1
二叉树的存储结构
1.顺序存储结构
依二叉树的性质,完全二叉树和满二叉树采用顺序存储比较合适,既不浪费空间,又可以根据公式计算出每一个结点的左、右孩子的位置。,但是,对于一般的二叉树,必须用‘虚结点’将其补成一棵“完全二叉树”来存储,这就会造成空间浪费。
#include "stdio.h" #include "stdlib.h" #define MaxSize 100 typedef char Elemtype; typedef struct TreeNode { Elemtype value; bool isEmpty; }; TreeNode t[MaxSize]; void InitTree(TreeNode t[MaxSize]) { for (int i = 0; i < MaxSize; i++) { t[i].isEmpty = true; } } void CreateTree(TreeNode t[MaxSize]) { for (int i = 1; t[i].value!='\0'; i++) { scanf_s("%c\n", &t[i].value); t[i].isEmpty = false; } }
//寻找最近公共结点 Elemtype Search(TreeNode t[MaxSize], int i, int j) { if (!(t[i].isEmpty && t[j].isEmpty)){ while (i != j) { if (i > j) i = i / 2; else j = j / 2; } return t[i].value; } } void main() { TreeNode t[MaxSize]; InitTree(t); CreateTree(t); Search(t,4,9); system("pause"); }
2.链式存储结构
二叉树一般采用链式存储结构;二叉链表至少包含三个域:数据域、左指针域、右指针域
若二叉树有n个结点,,则它的二叉链表中有2n个链域,其中有n-1个非空链域,其余都是空链域,空链域有n+1个,利用这些链域可组成另一种链表结构---线索链表。
(1)找i 、j 两结点最近的公共祖先结点;
分析二叉树中任意两个结点必然存在最近的公共祖先结点,最坏的情况下是根结点,而且从最近的公共祖先结点到根结点的全部祖先结点都是公共的:
若 i> j,i的双亲结点i/2,若i/2=j,则结点i/2是原结点i和结点j的最近公共祖先结点,否则 i=i/2;
若j > i, 结点j的双亲结点为结点j/2,若 j/2=i,则结点j/2是原结点i和结点j的最近公共祖先结点, 否则 j=j/2
重复上述过程,直到找到为止;
//找两结点最近的公共祖先结点 ElemType CommonAncestor(SeqTree T, int i, int j) { if (T[i] != '#' && T[j] != '#') { while (i != j) { if (i > j) i = i / 2; else j = j / 2; } return T[i]; } } BiTNode* CommonAncestor2(BiTree *T, BiTNode *p,BiTNode *q) { if (T == NULL) return NULL; if (p == T || q == T) return T; BiTNode left = CommonAncestor2(T->lchild, p, q); BiTNode right = CommonAncestor2(T->rchild, p, q); if (left != null && right != null) { return T; } return left != null ? left : right; }

浙公网安备 33010602011771号