二叉树:
一种具有一对多层次关系的数据结构
有且只有一个没有前驱的节点,称为根节点root
注意:树型结构具有递归型
是一种常用的数据结构,比普通树处理起来要简单,而且普通也比较方便地转换成二叉树
定义:节点的度最多为2
二叉树是n个有限元素的集合,该集合或者为空、或者由一个称为根(root)的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成,是有序树。当集合为空时,称该二叉树为空二叉树。在二叉树中,一个元素也称作一个节点
特殊的二叉树类型:
满二叉树:每层的节点数都是2^(i-1)
完全二叉树:深度为k,有n个节点的二叉树当且仅当其每一个节点都与深度为k的满二叉树中编号从1到n的节点一一对应时,称为完全二叉树
二叉树的重要性质:(重点)
性质1:二叉树的第i层上至多有2^(i-1)(i≥1)个节点
性质2:深度为h的二叉树中至多含有2^h-1个节点
性质3:若在任意一棵二叉树中,有n0个叶子节点,有n2个度为2的节点,则必有n0=n2+1
性质4:具有n个节点的满二叉树深为log2n+1
性质5:若对一棵有n个节点的完全二叉树进行顺序编号(1≤i≤n),那么,对于编号为i(i≥1)的节点:
当i=1时,该节点为根,它无双亲节点
当i>1时,该节点的双亲节点的编号为i/2。
若2i≤n,则有编号为2i的左节点,否则没有左节点
若2i+1≤n,则有编号为2i+1的右节点,否则没有右节点
二叉树的操作:
构建、销毁、遍历、高度、密度、插入、删除、查询、求左、求右、求根
二叉树的存储:
顺序存储:必须按照完全二叉树的格式,把每个节点按照从上到下、从左到右的顺序依次存入连续的内存中,如果有空位置则使用特殊
数据代替存入
数据项:
存储节点的内存首地址
容量
二叉树的遍历(重点)
前序:根、左、右
中序:左、根、右
后序:左、右、根
层序:从上到下、从左到右依次遍历一棵树
注意:前中后由根节点决定,并且左右子树的遍历顺序不会改变
注意:根据 前序+中序 或者后序+中序 就可以还原一棵树,只有 前序+后序 是无法还原的
注意:层序遍历
#include
#include
#include
#include
#include "list_queue.h"
// 顺序二叉树
#define TREE_TYPE char
#define EMPTY '#'
typedef struct BinTree
{
TREE_TYPE* arr;
size_t cal;
}BinTree;
// 构建
BinTree* create_tree(TREE_TYPE* arr,size_t len)
{
BinTree* tree = malloc(sizeof(BinTree));
tree->arr = malloc(sizeof(TREE_TYPE)*len);
memcpy(tree->arr,arr,sizeof(TREE_TYPE)*len);
tree->cal = len;
return tree;
}
// 对于编号为index的节点进行前序遍历
void _dlr_show(BinTree* tree,size_t index)
{
if(index > tree->cal || EMPTY == tree->arr[index-1])
return;
printf("%c",tree->arr[index-1]);
_dlr_show(tree,2*index);
_dlr_show(tree,2*index+1);
}
// 前序
void dlr_show(BinTree* tree)
{
_dlr_show(tree,1);
printf("\n");
}
void _ldr_show(BinTree* tree,size_t index)
{
if(index > tree->cal || EMPTY == tree->arr[index-1])
return;
_ldr_show(tree,2*index);
printf("%c",tree->arr[index-1]);
_ldr_show(tree,2*index+1);
}
// 中序
void ldr_show(BinTree* tree)
{
_ldr_show(tree,1);
printf("\n");
}
void _lrd_show(BinTree* tree,size_t index)
{
if(index > tree->cal || EMPTY == tree->arr[index-1])
return;
_lrd_show(tree,2*index);
_lrd_show(tree,2*index+1);
printf("%c",tree->arr[index-1]);
}
// 后序
void lrd_show(BinTree* tree)
{
_lrd_show(tree,1);
printf("\n");
}
// 层序
void level_show(BinTree* tree)
{
// 创建队列
ListQueue* queue = create_list_queue();
// 根节点编号入队
push_list_queue(queue,1);
while(!empty_list_queue(queue))
{
// 获取队头
int index = front_list_queue(queue);
// 计算左子树编号,检查后入队
int left = index*2;
if(left <= tree->cal && EMPTY != tree->arr[left-1])
push_list_queue(queue,left);
// 计算右子树编号,检查后入队
int right = index*2+1;
if(right <= tree->cal &&
EMPTY != tree->arr[right-1])
push_list_queue(queue,right);
// 队头出队
pop_list_queue(queue);
// 打印
printf("%c",tree->arr[index-1]);
}
// 销毁队列
destory_list_queue(queue);
printf("\n");
}
//计算index编号节点的高度
int _high_tree(BinTree* tree,size_t index)
{
if(index > tree->cal || EMPTY == tree->arr[index-1])
return 0;
int lh = _high_tree(tree,index*2);
int rh = _high_tree(tree,index*2-1);
return lh>rh?lh+1:rh+1;
}
//树的高度
int high_tree(BinTree* tree)
{
return _high_tree(tree,1);
}
//计算某个节点的密度
int _density_tree(BinTree* tree,size_t index)
{
if(index > tree->cal || EMPTY == tree->arr[index-1])
return 0;
return _density_tree(tree,index*2)+_density_tree(tree,index*2+1);
}
//树的密度
int density_tree(BinTree* tree)
{
return _density_tree(tree,1);
}
//插入
bool insert_tree(BinTree* tree,TREE_TYPE pdata,TREE_TYPE data)
{
size_t index = 1;
while(index <= tree->cal)
{
if(tree->arr[index-1] == pdata)
{
if(index*2 > tree->cal || index*2+1>tree->cal)
{
// 没有左右子树,扩容
tree->cal*=2;
tree->arr = relloc(tree->arr,tree->cal*sizeof(TREE_TYPE));
// 并且给新增的位置置空EMPTY
for(int i = tree->cal;i
tree->arr[i] = EMPTY;
tree->cal *= 2;
}
if(EMPTY == tree->arr[index*2-1])
{
tree->arr[index*2-1] = data;
return true;
}
if(EMPTY == tree->arr[index*2])
{
tree->arr[index*2] = data;
return true;
}
return false;
}
index++;
}
return false;
}
//删除 只能删除叶子节点
bool del_tree(BinTree* tree,TREE_TYPE data)
{
size_t index = 1;
while(index <= tree->cal)
{
if(data == tree->arr[index-1])
{
if(index*2 <= tree->cal && EMPTY != tree->arr[index*2-1])
return false;
if(index*2+1 < tree->cal && EMPTY != tree->arr[index*2])
return false;
tree->arr[index-1] = EMPTY;
return true;
}
index++;
}
return false;
}
int main(int argc,const char* argv[])
{
char* str = "ABCD#EF#G##H";
BinTree* tree = create_tree(str,strlen(str));
insert_tree(tree,'B','X');
dlr_show(tree);
ldr_show(tree);
lrd_show(tree);
level_show(tree);
printf("high:%d\n",high_tree(tree));
}