一種二叉搜索樹實現

今天嘗試使用C語言實現一顆二叉搜索樹(Binary Search Tree),發現其中最複雜的是Delete過程,說他複雜並不是其過程難以理解,而是需要用到遞歸,尤其是當遞歸函數需要返回值時,不知道中間遞歸(相對於尾遞歸而言)該如何使用,於是自己又重新梳理一下遞歸,總算將其搞明白了,爲了防止遺忘,故寫下此文。

#include<stdio.h>
#include<stdlib.h>

struct BTNode {
	int data;
	struct BTNode *lchild;
	struct BTNode *rchild;
};

struct BTNode *insert(struct BTNode *T,int n)
{
	if(T == NULL)
	{
		T = malloc(sizeof(struct BTNode));
		if(T == NULL)
		{
			printf("Error: out of memory!!\n");
			return NULL;
		}
		else
		{
			T->data = n;
			T->lchild = T->rchild = NULL;
		}
	}
	else
	{	
		if(n < T->data)
			T->lchild = insert(T->lchild,n);
		else if(n > T->data)
			T->rchild = insert(T->rchild,n);
	}
	return T;
}

struct BTNode *find(struct BTNode *T,int n)
{
	if(T == NULL)
		return NULL;
	if(T->data == n)
		return T;
	else if(n < T->data)
		return find(T->lchild,n);
	else
		return find(T->rchild,n);
}

struct BTNode *findMin(struct BTNode *T)
{
	if(T == NULL)
	{
		printf("this is a empty tree\n");
		return NULL;
	}
	while(T->lchild != NULL)
		T = T->lchild;
	return T;
}

struct BTNode *findMax(struct BTNode *T)
{
	if(T == NULL)
	{
		printf("this is a empty tree\n");
		return NULL;
	}
	while(T->rchild != NULL)
		T = T->rchild;
	return T;
}

struct BTNode *delete(struct BTNode *T,int n)
{
	struct BTNode *temp;
	if(T == NULL)
	{
		return NULL;
	}
	if(n < T->data)
		T->lchild = delete(T->lchild,n);
	else if(n > T->data)
		T->rchild = delete(T->rchild,n);
	else {
		if(T->lchild && T->rchild)
		{
			temp = findMin(T->rchild);
			T->data = temp->data;
			T->rchild = delete(T->rchild,temp->data);
		}
		else
		{
			temp = T;
			if(T->lchild == NULL && T->rchild == NULL)
				T = NULL;
			else if(T->lchild == NULL)
				T = T->rchild;
			else
				T = T->lchild;
			free(temp);
		}
	}
	return T;
}

void print_preorder(struct BTNode *T)
{
	if(T == NULL)
		return;
	printf("\t%d\t",T->data);
	print_preorder(T->lchild);
	print_preorder(T->rchild);
	return;
}

void print_midorder(struct BTNode *T)
{
	if(T == NULL)
		return;
	print_midorder(T->lchild);
	printf("\t%d\t",T->data);
	print_midorder(T->rchild);
	return;
}

void print_postorder(struct BTNode *T)
{
	if(T == NULL)
		return;
	print_postorder(T->lchild);
	print_postorder(T->rchild);
	printf("\t%d\t",T->data);
	return;
}

int main(void)
{
	struct BTNode *T = NULL;
	T = insert(T,10);
	T = insert(T,8);
	T = insert(T,16);
	T = insert(T,11);
	T = insert(T,13);
	T = insert(T,18);

	printf("當前樹的前序遍歷爲:");
	print_preorder(T);
	printf("\n");

	printf("當前樹的中序遍歷爲:");
	print_midorder(T);
	printf("\n");

	printf("當前樹的後序遍歷爲:");
	print_postorder(T);
	printf("\n");

	struct BTNode *position;
	position = find(T,15);
	if(position == NULL)
		printf("15 not found in current tree\n");
	else
		printf("%d is in current tree\n",position->data);
	
	position = findMin(T);
	printf("%d is Min value in current tree\n",position->data);

	position = findMax(T);
	printf("%d is Max value in current tree\n",position->data);

	printf("---------------start to delete 10------------------\n");
	position = delete(T,10);

	printf("---------------after delete 10---------------------\n");
	printf("當前樹的前序遍歷爲:");
	print_preorder(T);
	printf("\n");

	printf("當前樹的中序遍歷爲:");
	print_midorder(T);
	printf("\n");

	printf("當前樹的後序遍歷爲:");
	print_postorder(T);
	printf("\n");
	
	return 0;
}

運行結果如下:


發佈了36 篇原創文章 · 獲贊 11 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章