肥貓學習日記------二叉樹(數組)

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