树的基础知识
树的定义
------树是一个节点或者多个节点的集合
/例如
如图: A、B、C…M ,这棵树是这13个节点的集合
*/
树的作用
------组织数据时,数据信息按照树分支的形式进行关联。
树的特性
1、存在一个称为根的特定节点(图中 1 节点则为这棵树的根节点)
2、其余节点被分成n≥ 0 个互不相交的结合T1,T2… Tn. 其中每个集合都是一棵树,其中T1…Tn称为根节点的子树。
【关于树的术语】
节点
------代表信息项和指向其他节点的分支
节点的度(degree)
------指该节点的子树数目
/*例如
节点A的子树有三个, 分别为 B 、C 、D
节点H的子树有一个,分别为 M
*/
树的度(degree of tree)
1、是树中所有节点的度的最大值
2、度为0的节点称为叶子 ( Leaf ) 或者终端节点 ( Terminal node )
/*例如
图中的树,节点中度最大的节点为A和D,度为3。这样本树的最大度为3。
图中的叶子节点有 K、L 、G 、M、 J
*/
节点之间的关系
1、父亲节点 具有子树的节点称为这些子树根节点的父亲节点
2、儿子节点 子树的根节点称为该节点的儿子
3、兄弟 同一个父亲的儿子可以称为兄弟
4、祖先 一个节点的祖先是该节点到"根节点"的路径上的所有节点
5、后代 该节点的子树中包含的所有节点
6、节点的层 所有节点的层都是其父亲节点的层数+1 ,根节点是第一层
7、树的深度或者高度 树中最大的层号
/*
例如
1、子树E 和 F是子树B的真子集,节点E 和 F是子树 E 和F的根节点,B 和 E 与 F 相连且是B的子树, 所以 E 和 F是B 的根节点
2、反过来,这些子树的根节点就是 E 和F ,E 和 F 就是 B 的儿子
3、E 和 F 都是 B的儿子,而 B 是 E 和 F 的父亲
4、B树下,K的祖先有E 和 B ,A 树下 M节点的祖先有 H D A
5、B 树下的 E F K L
6、例如 B 节点的层数是2 , E节点的层数是3
7、该图中的最大层数是 节点K L M的层数,都为4 ,所以该树的深度或者高度为4
*/
介绍完了树的一些基本概念,现在开始介绍树的存储表示方式
树的存储表示
简介:除了图示法表示树以外,还有很多方法可以表示一棵树
【列表存储】的表示方法
------树中的任何一个子树都是一个列表
如图中的树可以表示为 (1(2(4(8,9),5(10,11)),3(6,7)))
注意根节点放在最前面,随后是各节点组成的子树
/*例如
树2的表示( 2 ( 4 ( 8 , 9 ) , 5 ( 10 , 11 ) ) )
*/
【左儿子-右兄弟】的表示方法
-------对于固定大小的节点操作比较容易,是一种研究节点大小固定的存储方法
-------每个节点恰好都需要两个链域或者指针域
这种形式的图后期再补
【2度树】的表示方法 【也就是平时用到的二叉树形式】
**可以把普通树图 -> 左儿子右兄弟->二叉树图 **
任意节点的树通过上述形式都可以转换成二叉树
------就是把“左兄弟-右儿子”的图顺时针旋转45°就可以了
------在"左儿子-右兄弟"的图中没有右兄弟的根节点一定没有右儿子(图例很容易看出来)
这种形式的图也后期再补
好了,现在介绍了树的概念和树的三种存储方式,开始介绍二叉树,其实树的存储方式就是通过转变树图的结构,然后更加方便的通过代码来实现
二叉树
二叉树与树的概念完全不同
二叉树任意节点的度都不会超过二
二叉树的节点要区分左儿子和右儿子,而树的节点的子树的顺序不重要
二叉树可以为空,但是树必须要有一个根节点
二叉树的左儿子与右儿子要区分,比如一棵树的根节点只有左儿子,另一颗树的根节点只有右儿子,这两棵树是不同的
【二叉树的定义】
------是有限多个节点的集合,这个集合可以是空寂,或者是一个根节点和两颗互不相交的、分别称为左节点和右节点的左子树和右子树组成
【抽象数据型】
//struct Binary_Tree(缩写BinTree)
//通过链表的形式实现
typedef struct node{
int data //数据域
struct node* left ; //左节点
struct node* right; //右节点
}Node; //节点实例
//struct BinRoot
typedef struct{
Node *root;
}Tree;
//BinTree CreatBTree(Tree* tree ,int value) //this part of code from baidu
void CreatBTree(Tree* tree, int value)//创建树
{
Node* node = (Node*)malloc(sizeof(Node));//创建一个bai节点
node->data = value;
node->left = NULL;
node->right = NULL;
if (tree->root == NULL)//判断树是不是du空树 {
tree->root = node;
}
else
{//不是空树
Node * temp = tree->root;//从树根开始
while (temp != NULL)
{
if (value < temp->data)//小于就进左儿子
{
if (temp->left == NULL)
{
temp->left = node;
return;
}
else
{//继续判断
temp = temp->left;
}
}
else {//否则进右儿子
if (temp->right == NULL)
{
temp->right = node;
return;
}
else {//继续判断
temp = temp->right;
}}}}
return;
}