目录
下一篇: 二叉树的先中后序遍历
一、示例树(完全二叉树):
存储结构
1、结构定义:
//顺序存储
#define MaxSize 100
struct TreeNode{
int value;//结点中的数据元素
bool isEmpty;//结点是否为空
};
//定义一个数组存储完全二叉树
TreeNode t[MaxSize];
void init(){
//初始化时要将所有的结点标记为空
for(int i=0;i<MaxSize;i++){
t[i].isEmpty=true;
}
}
2、基本操作:
i的左孩子 | 2i |
i的右孩子 | 2i+1 |
i的父节点 | [i/2] |
i所在的层次 |
|
若完全二叉树中共有n个结点,则
判断i是否有左孩子 | 2i<=n |
判断i是否有右孩子 | 2i+1<=n |
判断i是否是叶子/分支结点 | i>[n/2] |
二、非完全二叉树
示例树
若这么存储
则无法从结点编号中反应出结点间的逻辑关系
我们可以把上图中不存在的结点补充进来,模仿完全二叉树
那样就可以使用完全二叉树的方式判断
i的左孩子
i的右孩子
i的父结点
但是判断i是否有左孩子、右孩子、i是否是叶子/分支结点,则还需要判断isEmpty是空还是有
当然会很浪费空间
最坏情况:
高度为h且只有h个结点的单支树(所有结点只有右孩子),但至少需要2^h-1个存储单元
结论:二叉树的顺序存储及结构,只适合存储完全二叉树
链式存储
//链式存储
typedef struct BiTNode{
int data;//数据域
struct BiTNode *lchild,*rchild;//左右孩子指针
//struct BiTNode *parent;//父结点指针,三叉链表----方便找到父结点
}BiTNode,*BiTree;
/*
若有n个结点则有2n个指针,有n-1个结点被指针所连接
所以有n+1个空链域,可以用来构造线索二叉树
不难发现,找到指定结点p的左/右孩子很简单,但是找父结点就只能从根开始遍历
可以构造三叉链表,多了一个指向父结点的指针
*/
int main(){
//定义一个空树
BiTree root=NULL;
//插入根结点
root=(BiTree)malloc(sizeof(BiTNode));
root->data={1};
root->lchild=NULL;
root->rchild=NULL;
//插入新结点
BiTNode *p =(BiTNode *)malloc(sizeof(BiTNode));
p->data={2};
p->lchild=NULL;
p->rchild=NULL;
root->lchild=p;//作为根结点的左孩子
}