树
树:元素之间存储一对多关系的数据结构,常用语表现族谱关系、组织关系等,也可以借助特殊的树型结构实现查找、排序的算法,一般使用倒悬树的方式表示
相关术语
根结点:树的最上层元素,有且只能有一个
子结点:该结点对应的下一层元素
父结点:该结点对应的上一层元素
叶子结点:没有子结点的元素,一般处于树的最底层或最底层的上一层
兄弟结点:具有同一父结点的元素,处在同一层
高度:树的层数
密度:树的结点数
度:结点的子结点数量
树分为很多种,今天要介绍的是完全二叉树
二叉树的遍历分为以下三种情况
1、前序遍历:根左右
2、中序遍历:左根右
3、后序遍历:左右根
4、层序遍历(广度遍历):从上到下,先左后右
建立树(数组)
#define TYPE int
#define NUL 0
typedef struct BinTree
{
TYPE* arr;
size_t cal;
}BinTree;
BinTree* creat_tree(size_t cal)
{
BinTree* tree=malloc(sizeof(BinTree));
tree->arr = calloc(cal,sizeof(TYPE));
tree->cal=cal;
}
对数进行操作
初始化树
void init_tree(BinTree* tree,TYPE* arr,size_t len)
{
memcpy(tree->arr,arr,sizeof(TYPE)*len);
}
左右结点
TYpe* lchild_tree(BinTree* tree,TYPE data)//左结点
{
for(int i =0;i<tree->cal;i++)
{
if(tree->arr[i] == data && tree->arr[i*2+1])
{
return tree->arr+i*2+1;
}
}
return NULL;
}
TYpe* rchild_tree(BinTree* tree,TYPE data)//右结点
{
for(int i =0;i<tree->cal;i++)
{
if(tree->arr[i] == data && tree->arr[i*2+2])
{
return tree->arr+i*2+2;
}
}
return NULL;
}
左右兄弟
TYPE* lbrother_tree(BinTree* tree,TYPE data)//左兄弟
{
if(tree->arr[0] == data) return NULL;
//该结点必须是右子结点,下标必须是偶数
for(int i=0;i<tree->cal;i++)
{
if(tree->arr[i] == data && 0 == i%2)
{
return tree->arr+i-1;
}
}
return NULL;
}
TYPE* rbrother_tree(BinTree* tree,TYPE data)//右兄弟
{
if(tree->arr[0] == data) return NULL;
//该结点必须是左子结点,下标必须是奇数
for(int i=0;i<tree->cal;i++)
{
if(tree->arr[i] == data && i%2)
{
return tree->arr+i-1;
}
}
return NULL;
}
父结点
TYPE* parent_tree(BinTree* tree,TYPE data)
{
if(tree->arr[0] == data) return NULL;
for(int i=0;i<tree->cal;i++)
{
if(tree->arr[i] == data && tree->arr[(i-1)/2])
{
return tree->arr+(i-1)/2;
}
}
return NULL;
}
访问某一层的某一个结点
TYPE* access_tree(BinTree* tree,size_t level,size_t,order)
{
if(pow(2,level-1)<order) return NULL;
size_t i =pow(2,level-1)+order-2;
if(i>tree->cal) return NULL;
return tree->arr+i;
}
高度
size_t high_tree(BinTree* tree)
{
size_t i =tree->cal;
while(NUI == tree->arr[--i]);
printf("%d %d\n",i,tree->arr[i]);
size_t high = 0;
do{
high++;
}while(pow(2,high)-2<i)
return high;
}
遍历
前序遍历
void _prev_tree(BinTree* tree,size_t i)
{
printf("%d",tree->arr[i]);//根
if(NUL != tree->arr[i*2+1])//左
_prev_tree(tree,i*2+1);
if(NUL != tree->arr[i*2+2])//右
_prev_tree(tree,i*2+2);
}
void prev_tree(BinTree* tree)
{
_prev_shpw(tree,0);
printf("\n");
}
中序遍历
void _in_tree(BinTree* tree,size_t i)
{
if(NUL != tree->arr[i*2+1])//左
_in_tree(tree,i*2+1);
printf("%d",tree->arr[i]);//根
if(NUL != tree->arr[i*2+2])//右
_in_tree(tree,i*2+2);
}
void in_tree(BinTree* tree)
{
_in_shpw(tree,0);
printf("\n");
}
后序遍历
void _post_tree(BinTree* tree,size_t i)
{
if(NUL != tree->arr[i*2+1])//左
_post_tree(tree,i*2+1);
if(NUL != tree->arr[i*2+2])//右
_post_tree(tree,i*2+2);
printf("%d",tree->arr[i]);//根
}
void post_tree(BinTree* tree)
{
_post_shpw(tree,0);
printf("\n");
}
层序遍历
void level_order_show(BinTree* tree)
{
size_t h =high_tree(tree);
printf("high:%d\n",h);
for(int i=0;i<h;i++)
{
printf("第%d行:",i);
for(int j=1;j<=pow(2,i-1);j++)
{
printf("%d",*access_tree(tree,i,j));
}
printf("\n");
}
}