樹
樹:元素之間存儲一對多關係的數據結構,常用語表現族譜關係、組織關係等,也可以藉助特殊的樹型結構實現查找、排序的算法,一般使用倒懸樹的方式表示
相關術語
根結點:樹的最上層元素,有且只能有一個
子結點:該結點對應的下一層元素
父結點:該結點對應的上一層元素
葉子結點:沒有子結點的元素,一般處於樹的最底層或最底層的上一層
兄弟結點:具有同一父結點的元素,處在同一層
高度:樹的層數
密度:樹的結點數
度:結點的子結點數量
樹分爲很多種,今天要介紹的是完全二叉樹
二叉樹的遍歷分爲以下三種情況
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");
}
}