1. 程式人生 > >二叉樹鏈式儲存及相關操作

二叉樹鏈式儲存及相關操作

      先序建立二叉樹、後序遞迴遍歷二叉樹、中序非遞迴遍歷二叉樹、層次遍歷二叉樹、非遞迴演算法求二叉樹深度、遞迴演算法求二叉樹深度、求分支結點個數、判斷是否為完全二叉樹、先序遍歷第k個結點的值、刪除值為k的結點及其子樹。

#include "stdio.h"
#include "stdlib.h"
#include "malloc.h"

typedef struct TNode           //二叉樹結構體定義
{
	int data;
	struct TNode *lchild, *rchild;
}TNode, *Tree;

typedef struct                 //棧結構體定義
{
	Tree data[100];
	int top;
} Stack;

typedef struct queue           //佇列結構體定義
{
	Tree data[100];
	int front, rear;
} queue;

int i = 0;

void create(Tree &T);            //先序建立二叉樹
void postorder(Tree T);          //後序遞迴遍歷二叉樹
void inorder(Tree T);            //中序非遞迴遍歷二叉樹
void levelorder(Tree T);         //層次遍歷二叉樹
void depth1(Tree T);             //非遞迴演算法求二叉樹深度
int depth2(Tree T);              //遞迴演算法求二叉樹深度
int  count(Tree T);              //求分支結點(度不為0的結點)個數
int Iscomplete(Tree T);          //判斷是否為完全二叉樹 
void preorder_k(Tree T, int k);  //先序遍歷第k個節點的值
void delete_k(Tree T);           //刪除值為k的結點及其子樹
void search(Tree T, int k);      //尋找值為k的結點

int main()
{
	int k;
	Tree T;

	printf("建立一棵二叉樹:\n");
	create(T);
	printf("後序遞迴遍歷二叉樹:\n");
	postorder(T);
	printf("\n");
	printf("中序非遞迴遍歷二叉樹:\n");
	inorder(T);
	printf("層次遍歷二叉樹:\n");
	levelorder(T);
	depth1(T);
	k = depth2(T);
	printf("該二叉樹高度為:%d\n", k);
	k = count(T);
	printf("該二叉樹分支結點個數為:%d\n", k);
	k = Iscomplete(T);
	if(k == 1)
		printf("該樹是完全二叉樹!\n");
	else
		printf("該樹不是完全二叉樹!\n");
	printf("你想知道第幾個結點的值?請任意輸入一個1-7的正整數。\n");
	scanf("%d", &k);
	preorder_k(T, k);
	printf("你想刪除值為幾的結點及其子樹?請任意輸入一個1-7的正整數。\n");
	scanf("%d", &k);
	search(T, k);
	printf("後序遞迴遍歷二叉樹:\n");
	postorder(T);
	printf("\n");

	return 1;
}

void create(Tree &T)          //先序建立二叉樹
{
	int a;
	scanf("%d", &a);
	if(a != 0)
	{
		T = (Tree)malloc(sizeof(TNode));
		T->data = a;
		create(T->lchild);
		create(T->rchild);
	}
	else
		T=NULL;
}

void postorder(Tree T)           //後序遞迴遍歷二叉樹
{
	if(T != NULL)
	{
		postorder(T->lchild);
		postorder(T->rchild);
		printf("%d ", T->data);
	}
}

void inorder(Tree T)            //中序非遞迴遍歷二叉樹
{
	Stack S;
	S.top = -1;
	Tree p = T;

	while(p != NULL || S.top != -1)
	{
		while(p != NULL)
		{
			S.data[++S.top] = p;
			p = p->lchild;
		}
		if(S.top != -1)
		{
			p = S.data[S.top--];
			printf("%d ", p->data);
			p = p->rchild;
		}		
	}
	printf("\n");
}

void levelorder(Tree T)         //層次遍歷二叉樹
{
	queue q;
	q.front =q.rear = 0;
	Tree p = T;
	q.data[q.rear++] = p;
	while(q.front < q.rear)
	{	
		p = q.data[q.front++];	
		printf("%d ", p->data);
		if(p->lchild != NULL)
			q.data[q.rear++] = p->lchild;
		if(p->rchild != NULL)
			q.data[q.rear++] = p->rchild;
	}
	printf("\n");
}

void depth1(Tree T)            //非遞迴求二叉樹深度
{
	int h = 0, last = 0;
	queue q;
	q.front = q.rear = -1;
	Tree p = T;
	q.data[++q.rear] = p;

	while(q.front < q.rear)
	{
		p = q.data[q.front++];
		if(p->lchild)
			q.data[++q.rear] = p->lchild;
		if(p->rchild)
			q.data[++q.rear] = p->rchild;
		if(q.front == last)
		{
			++h;
			last = q.rear + 1;
		}
	}
	printf("該二叉樹高度為:%d\n", h);
}

int depth2(Tree T)            //遞迴求二叉樹深度
{
	int h1, h2;
	if(T == NULL)
		return 0;
	else
	{
		h1 = depth2(T->lchild);
		h2 = depth2(T->rchild);
	}

	if(h1 >= h2)
		return h1 + 1;
	else
		return h2 + 1;
}

int count(Tree T)             //遞迴求分支結點個數
{
	int h1, h2;
	if(T == NULL)
		return 0;
	h1 = count(T->lchild);
	h2 = count(T->rchild);
	
	if(T->lchild != NULL || T->rchild != NULL)
		return h1 + h2 +1;
}

int Iscomplete(Tree T)       //判斷是否為完全二叉樹
{
	Tree p;
	queue q;
	q.front = q.rear = 0;
	if(!T)
		return 1;
	q.data[q.rear++] = T;
	while(q.front < q.rear)
	{
		p = q.data[q.front++];
		if(p)
		{
			q.data[q.rear++] = p->lchild;
			q.data[q.rear++] = p->rchild;
		}
		else
			while(q.front < q.rear)
			{
				p = q.data[q.front++];
				if(p)
					return 0;
			}
	}
	return 1;
}

void preorder_k(Tree T, int k)   //先序遍歷第k個結點的值
{
	if(T != NULL)
	{
		if(++i == k)
			printf("第%d個值為%d!\n", i, T->data);
		preorder_k(T->lchild, k);
		preorder_k(T->rchild, k);
	}
}

void delete_k(Tree T)            //刪除值為k的結點及其子樹
{
	if(T != NULL)
		{
			delete_k(T->lchild);
			delete_k(T->rchild);
			free(T);
		}
}

void search(Tree T, int k)       //尋找值為k的結點
{
	Tree p;
	queue q;
	q.front = q.rear = -1;
	if(T != NULL)
	{
		if(k == T->data)
		{
			delete_k(T);
			exit(1);
		}
		q.data[++q.rear] = T;
		while(q.front < q.rear)
		{
			p = q.data[++q.front];

			if(p->lchild != NULL)
				if(p->lchild->data == k)
				{	
					delete_k(p->lchild);
					p->lchild = NULL;
				}
				else
					q.data[++q.rear] = p->lchild;

			if(p->rchild != NULL)
				if(p->rchild->data == k)
				{
					delete_k(p->rchild);
					p->rchild = NULL;
				}
				else
					q.data[++q.rear] = p->rchild;
		}
	}
}