树与二叉树
-
树的概念及性质
-
树的存储结构
-
树和森林的遍历
-
二叉树的概念和性质
-
二叉树的存储结构
-
二叉树的遍历
-
线索二叉树
-
树与二叉树的相互转换
-
树与二叉树的应用
并查集
二叉排序树
平衡二叉树
哈夫曼树
一、 树的概念与性质(基础数学知识在此不予推导)
- 树的结点数=边数+1=所有结点的度数+1
- 度为m的树在第i层最多有m^i-1个结点
二、树的存储结构
- 双亲表示法:采用一组连续的存储空间,同时在每个结点中增设一个伪指针指向其父结点的数组下标(可对比静态链表哦)
树的双亲存储
typedef struct{
Elemtype data;
int parent;
}PNode;
typedef struct {
PNode tree[Maxsize];
int n;
};
- 孩子表示法(又称为二叉树表示法,即是以二叉链表为存储结构存储)
孩子表示法
typedef struct Node {孩子结点
int child;
struct Node *next;
}TNode;
typedef struct {数组
Thead str[Maxsize];
int n;
};
typedef struct {表头结构
TNode*head;
int data;
}Thead;
- 孩子兄弟表示法
每个结点包含三部分 :结点值,指向其第一个孩子节点的指针,指向其兄弟的指针
孩子兄弟表示法
typedef struct Node{
int data;
struct Node *lchild,rbro;
}CSNode;
三、树和森林的遍历
- 树遍历方式:1、先序遍历 2、后序遍历 3、层次遍历
- 森林的遍历:1、先序遍历2、中序遍历(森林的中序遍历是宏观的对每个树其实还是后序遍历的)
四、二叉树的概念及性质 - 度为二的树和二叉树的区别
1、度为二的树最少有3个结点,而二叉树可以为空
2、二叉树是有序树,只有一个度的结点也要分左右孩子 - 完全二叉树中结点的度为一(即只有一个孩子)的结点只有一个或者没有
五、二叉树的存储结构 - 顺序存储
由图可看出顺序存储适合满二叉树和完全二叉树的存储
且一般二叉树想用数组存储需要将其转化为完全二叉树,这时就需要增加很多空结点 - 链式存储
六、 二叉树的遍历 - 先序遍历
递归代码
void Preder(BiTree T)
{
if(T)printf("%d",T->data);
Preder(T->lchild);
Preder(T->rchild);
}
非递归代码
void Proder(BiTree T)
{
InitStack(S);
BiTree p=T;
while(p||!isEmpty(S)){
if(p){
visit(p);
Push(S,p);
p=p->child;
}
else{
Pop(S,p);
p=p->child;
}
}
}
- 中序遍历
递归代码
void Inorder(BiTree T)
{
Inorder(T->lchild);
if(T)printf("%d",T->data);
Inorder(T->rchild);
}
非递归代码
void Proder(BiTree T)
{
InitStack(S);
BiTree p=T;
while(p||!isEmpty(S)){
if(p){
Push(S,p);
p=p->child;
}
else{
Pop(S,p);
visit(p);
p=p->child;
}
}
}
- 后序遍历
void
- 层次遍历
void Levelorder(BiTree T)
{
InitQueue(Q);
BiTree p;
EnQueue(Q,T);
while(!isEmpty(Q)){
DeQueue(Q,p);
visit(p);
if(p->lchild)EnQueue(Q,p->lchild);
if(p->rchild)EnQueue(Q,p->rchild);
}
}
七、线索二叉树
节点定义
typedef struct Node{
int data;
struct Node *lchild,rchild;
int ltag,rtag;
}LNode;
八、树与二叉树的转换
树----->二叉树:兄弟变右儿子
二叉树---->树:右儿子变兄弟