树的定义
树是n(n>=0)个结点的有限集。
n=0称为空树。
在任意一个非空树中:
(1)有且仅有一个特定的称为根的结点;
(2)当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1,T2,,,,,Tm,其中每一个集合本身又是一棵树,并且称为根的子树。
结点分类:
结点的度:结点拥有的子树数。
叶结点/终端结点:度为零的结点。
非终端结点/分支结点:度不为0的结点。
内部节点:除根结点之外的分支结点。
树的度:树内各结点的度的最大值。
结点间关系:
结点的孩子:结点的子树的根,该结点称为孩子的双亲。
层次:从根开始定义,根为第一层,根的孩子为第二层。
树的深度或高度:树中结点的最大层次。
有序树:如果将树中结点的各子树看成从左至右是有次序的,不能互换的。
森林:m颗互不相交的树的集合。
线性结构与树结构的比较:
线性结构:第一个元素无前驱最后一个元素无后继中间元素一个前驱一个后继。
树结构:根结点无双亲叶结点无孩子可以多个中间结点一个双亲多个孩子。
树的存储结构:
双亲表示法:
在每个结点中附设一个指示器指示其双亲结点到链表中的位置。
结构定义代码
/* 树的双亲表示法结点结构定义 */ #define MAX_TREE_SIZE 100 typedef int TElemType; /* 树结点的数据类型,目前暂定为整型 */ typedef struct PTNode /* 结点结构 */ { TElemType data; /* 结点数据 */ int parent; /* 双亲位置 */ };PTNode; typedef struct /* 树结构 */ { PTNode nodes[MAX_TREE_SIZE]; /* 结点数组 */ int r,n; /* 根的位置和结点数 */ }PTREE;
根结点的位置域为-1.
长子域:结点最左边孩子的域。
没有孩子的结点长子域为-1.
右兄弟域,右兄弟不存在则赋值-1.
孩子表示法:
每个结点有多个指针域,其中每个指针指向一颗子树的根结点,我们把这种方法叫做多重链表表示法。
把每个结点的孩子结点排列起来,以单链表做存储结构,则n个孩子有n个孩子链表,如果是叶子结点则此单链表为空。 //孩子结点
然后n个头指针又组成一个线性表,采用顺序存储结构,存放进一个一维数组中。 //表头结点
1 /* 树的孩子表示法结构定义 */ 2 #define MAX_TREE_SIZE 100 3 typedef struct CTNode /* 孩子结点 */ 4 { 5 int child; 6 struct CTNode *next; 7 }*ChildPtr; 8 typedef struct /* 表头结构 */ 9 { 10 TElemType data; 11 ChildPtr firstchild; 12 }CTBox; 13 typedef struct /* 树结构 */ 14 { 15 CTBox nodes[MAX_TREE_SIZE]; /* 结点数组 */ 16 int r,n; /* 根的位置和结点数 */ 17 }CTree;
1 #define MAX_TREE_SIZE 100 2 typedef struct CTNode 3 { 4 int child; 5 struct CTNode *next; 6 } *ChildPtr; 7 typedef struct 8 { 9 TElemType data; 10 int parent; 11 ChildPtr firstchild; 12 }CTBox; 13 typedef struct 14 { 15 CTBox nodes[MAX_TREE_SIZE]; 16 int r,n; 17 }CTree;
孩子兄弟表示法:
设置两个指针分别指向该结点的第一个孩子和此结点的右兄弟。
typedef struct CSNode { TElemType data; struct CSNode *firstchild.*rightsib; } CSNode,*CSTree;
二叉树:
二叉树是n个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两个互不相交的、分别称为根结点的左子树和右子树的二叉树组成。
二叉树特点:
1,每个结点最多有两颗子树,所以二叉树中不存在度大于2的结点。
2,左子树和右子树是有顺序的,次序不能颠倒。
3,即使树中某结点只有一颗子树也要区分是左子树还是右子树。
二叉树的五种基本形态:
1,空二叉树2,只有一个根结点3,根结点只有左子树4,根结点只有右子树5,根结点既有左子树又有右子树。
斜树:左斜树和右斜树
左斜树:所有结点只有左子树的二叉树。
右斜树:所有结点只有右子树的二叉树。
线性结构可以理解为树的一种极其特殊的表现形式。
满二叉树:在一颗二叉树中所有的分支结点都存在左子树和右子树并且所有叶子都在同一层。
完全二叉树:对一颗具有n个结点的二叉树按层序编号,编号为i(1<i<=n)的结点与同样深度的满二叉树中编号为i的结点在二叉树中的位置完全相同。
二叉树的性质:
1,在二叉树的第i层上至多有2的i-1次方个结点
2,深度为k的二叉树至多有2的k次方-1个结点。
3,对于任何一颗二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0 = n2 +1.
4,具有n个结点的完全二叉树的深度为[log2n]+1
5,如果对一棵树有n个结点的完全二叉树的结点按层序编号,对任意结点i有
如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则双亲是结点[i/2]
如果2i>n,则结点i无左孩子,否则其左孩子是结点2i
3,如果2i+1>n,则结点i无右孩子;否则其右孩子是结点2i+1。
二叉树的存储结构:
二叉树顺序存储结构:顺序存储一般只用于完全二叉树。
二叉链表:二叉树设计一个数据域和两个指针域
typedef struct BitNode { TEleType data; struct BiTNode *lchild,*rchild; }BiTNode,*BiTree;