二叉查找树(中序遍历)

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

#define SIZE 10/*树的大小*/

typedef struct tronde {
	struct tronde* Left;
	struct tronde* Right;
	int key;
}Tronde;

typedef struct tree {
	Tronde* root;
	int size;/*项数*/
}Tree;

static Tronde* CopyEnptm(int x);
static void CopyDelte(Tronde* root);
static bool Find(Tronde* root, int x);
static void CopyEmDelete(Tronde** root, int x);
static void CopyDelete1(Tronde** root);

bool CopySize(Tree* Ptree);
bool CopyFull(Tree* Ptree);
bool FindTree(Tree* Ptree,int x);
void BuildTree(Tronde** lefRig, Tronde* x);
void InitializeTree(Tree* Ptree);
void AddNodeTree(Tree *Ptree,int x);
void EmptyDelete (Tree* Ptree);
void Delete(Tree* Ptree,int x);
void println(Tronde* root,void (*pfun)(int));/*函数指针*/

void showarray(int x);
int main(void) {
	Tree Ptree;
	InitializeTree(&Ptree);
	AddNodeTree(&Ptree, 10);
	AddNodeTree(&Ptree, 8);
	AddNodeTree(&Ptree, 7);
	AddNodeTree(&Ptree, 9);
	AddNodeTree(&Ptree, 12);
	AddNodeTree(&Ptree,11);
	AddNodeTree(&Ptree, 13);
	AddNodeTree(&Ptree, 3);
	AddNodeTree(&Ptree, 5);
	AddNodeTree(&Ptree, 6);
	if (!CopySize(&Ptree)) {/*查看树是否为空   其他操作都在这里完成*/
		println(Ptree.root, showarray);
		if (FindTree(&Ptree, 7))/*查找7这个数字*/
			printf("已在树中查到%d这个数字\n", 4);
		else
			printf("%d这个数字树中没有\n",4);
		Delete(&Ptree,8);
		Delete(&Ptree, 10);
		Delete(&Ptree, 11);
		Delete(&Ptree, 13);
		println(Ptree.root, showarray);

	}
	else
		puts("树为空");
	EmptyDelete(&Ptree, 4);
}
/*显示内容*/
void showarray(int x) {
	printf("Tree:%d\n", x);
}
/*初始化*/
void InitializeTree(Tree* Ptree){
	Ptree->root = NULL;
	Ptree->size = 0;
}
/*查看树是否为空*/
bool CopySize(Tree* Ptree) {
	return Ptree->size == 0;
}
/*查看树是否已满*/
bool CopyFull(Tree* Ptree) {
	return Ptree->size == SIZE;
}
/*生成根*/
void AddNodeTree(Tree* Ptree, int x) {
	Tronde* ps;
	Tronde* pn = Ptree->root;
	if (CopyFull(Ptree)) {
		printf("内容已满(添加内容为%d)\n",x);
		return;
	}
	ps = CopyEnptm(x);
	if (ps==NULL)/*判断是否申请成功*/
		exit(EXIT_FAILURE);
	if (pn == NULL) {
		Ptree->root = ps;
	}
	else {
		BuildTree(&Ptree->root, ps);
	}
	Ptree->size++;
}
/*生成左子右子(树)*/
void BuildTree(Tronde** lefRig, Tronde* x) {
	if (*lefRig != NULL) {
		if (x->key < (*lefRig)->key)
			BuildTree(&(*lefRig)->Left, x);
		else if (x->key > (*lefRig)->key) {
			BuildTree(&(*lefRig)->Right, x);
		}
	}
	else {
		*lefRig = x;
	}
}
/*一些赋值操作*/
static Tronde* CopyEnptm(int x){
	Tronde* pnew = (Tronde*)malloc(sizeof(Tronde));
	if (pnew==NULL)/*申请不成功*/
		return NULL;
	else {
		pnew->Left = NULL;
		pnew->Right = NULL;
		pnew->key = x;
	}
	return pnew;
}
/*查找*/
bool FindTree(Tree* Ptree, int x) {
	if (Ptree->root) {
		if (Find(Ptree->root,x))
			return true;
		else 
			return false;
	}
}
/*进行查找*/
static bool Find(Tronde* root, int x) {/*这里使用循环不使用递归当然可以使用递归*/
	while (root != NULL) {
		if (x < root->key)
			root = root->Left;
		else if (x > root->key)
			root = root->Right;
		else
			return true;
	}
	return false;
}
/*删除*/
void Delete(Tree* Ptree, int x) {
	if (Ptree->root) {
		CopyEmDelete(&Ptree->root, x);
	}
}
static void CopyEmDelete(Tronde** root, int x) {/*删除操作  (指针不熟的可能不知道这里为什么用二级指针 
												刚开始使用的是一级指针但是程序没有按照我的想法运行最后在dev里面测试了一下不在这讨论写完放下面)*/
	if (*root != NULL) {
		if (x <  (*root)->key) {
			CopyEmDelete(&(*root)->Left, x);
		}
		else if (x > (*root)->key) {
			CopyEmDelete(&(*root)->Right, x);
		}
		else {
			CopyDelete1(&(*root));
		}
	}
}
/*删除和连接操作*/
static void CopyDelete1(Tronde** root) {
	Tronde* temp;
	if ((*root)->Left == NULL) {
		temp = *root;
		*root = (*root)->Right;
		free(temp);
	}
	else if ((*root)->Right == NULL) {
		temp = *root;
		*root = (*root)->Left;
		free(temp);
	}
	else {
		for (temp = (*root)->Left; temp->Right != NULL; temp = temp->Right)
			continue;
		temp->Right = (*root)->Right;
		temp = *root;
		*root = (*root)->Left;
		free(temp);
	}
}
/*清空*/
void EmptyDelete(Tree* Ptree) {
	if (CopySize(Ptree))
		puts("树为空");
	else {
		if (Ptree->root) {
			CopyDelte(Ptree->root);
		}
	}
}
/*删除全部节点*/
static void CopyDelte(Tronde* root) {
	Tronde* printh;
	if (root != NULL) {
		printh = root->Right;
		CopyDelte(root->Left);
		free(root);
		CopyDelte(printh);
	}
}
/*查看树内容*/
void println(Tronde* root, void (*pfun)(int)) {
	if (root != NULL) {
		println(root->Left,(*pfun));
		(*pfun)(root->key);/*作用于*/
		println(root->Right, (*pfun));
	}
}

在上面的代码中有这段代码:static void CopyEmDelete(Tronde** root, int x)用到了二级指针,不经常用二级指针的可能不理解,举个例子:

int main(void){
    int *p;
    int **q;
    p=(int*)malloc(sizeof(int));
    printf("%d\n",p);
    q=&p;
    printf("%d",*q); 
    free(p);
}

输出的结果一样

 上面图中:temp指向p申请的空间,*q=指向temp;*q赋值为空,输出结果发现temp也变为空,而p不为空,总结也就是*q修改的是temp指向的内容,不修改p指向的内容.二级指针是操控一级指针的。

在上面递归函数调用中和这个同理,如果使用一级指针去删除那么最后在函数里面root修改的是自身指向的内容,当空间释放掉之后,我们删除的节点的父节点其中成员指向的内容将为垃圾值.说的有点麻烦理解一下.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值