ADT 二叉查找树

#include<stdio.h>
#include<stdlib.h>
#define NULL_DATA -1
typedef struct node
{
	int data;
	struct node*lchild;
	struct node*rchild;
}NODE;
//注:平均深度 O(log N)
NODE *create()
{
	NODE *t = (NODE*)malloc(sizeof(NODE));
	int x;
	if (t != NULL)
	{
		scanf("%d", &x);
		if (x == NULL_DATA)
		{
			t = NULL;
		}
		else
		{
			t->data = x;
			t->lchild = create();
			t->rchild = create();
		}
	}
	return t;
}
NODE* find(int x, NODE *t)
{
	if (t == NULL)
		return NULL;
	if (x<t->data)	//如果要查找的值小于根节点,那就递归查找左子树
		return(find(x, t->lchild));
	if (x>t->data)
		return(find(x, t->rchild));
	else
		return t;
}
NODE * findMin(NODE *t)//递归查找最小的节点
{
	if (t == NULL)
		return NULL;
	else if (t->lchild == NULL)
		return t;
	else	//由于左子树永远小于右子树,所以只需要遍历左边的
		return findMin(t->lchild);
}
NODE *insert(int x, NODE *t)
{
	if (t == NULL)//如果树本身就不存在,那就建立一颗新树,并把它的左右节点置为空
	{
		t = (NODE*)malloc(sizeof(NODE));
		t->data = x;
		t->lchild = t->rchild = NULL;
	}
	else
	{
		if (x<t->data)
			t->lchild = insert(x, t->lchild);
		if (x>t->data)
			t->rchild = insert(x, t->rchild);
	}
	return t;//最后返回的还是根节点
}
NODE* del(int x, NODE *t)
//删除有三种情况:1)没有子节点 2)有一个子节点 3)有两个子节点
{
	if (t == NULL)
	{
		printf("该树不存在!\n");
		return NULL;
	}
	else
	{
		if (x < t->data)
			t->lchild = del(x, t->lchild);
		else if (x > t->data)
			t->rchild = del(x, t->rchild);
		else if (x == t->data)
		{
			//如果左右节点均不存在,则直接删除
			NODE *temp = t;
			if (t->lchild == NULL)//若存在一个子节点,则把子节点的地址赋值给删除的那块节点
			{
				t= t->rchild;
				free(temp);
			}
			else if (t->rchild == NULL)
			{
				t = t->lchild;
				free(temp);
			}
			else if (t->lchild&&t->rchild)
			{//如果左右节点都存在,则找到右子树中最小的节点并代替它
				temp = findMin(t->rchild);
				t->data = temp->data;
				t->rchild = del(t->data, t->rchild);//找到之后再删除那个最小的节点
			}
		}
	}
	return t;
}
void print(NODE *t)
{
	if (t != NULL)
	{
		printf("%d  ", t->data);
		print(t->lchild);
		print(t->rchild);
	}
}
int main()
{
	//建立
	NODE *p,*e,*f,*g;
	int d;
	printf("先序输入ADT(查找二叉树)各节点的值,空值以-1替代。\n");
	p = create(); 
	e = f = p;
	//输出
	printf("二叉树的先序序列为:");
	print(p);
	//查找	
	printf("\n输入要查找的值:");
	scanf("%d", &d);
	p = find(d, p);
	if (p != NULL)
		printf("存在节点: %d\n", p->data);
	else
		printf("不存在该节点!\n");
	//插入
	printf("输入需要插入的值:");
	scanf("%d", &d);
	f = insert(d, f);
	printf("插入后的二叉树为:");
	print(f);
	//删除
	printf("\n输入需要删除的值:");
	scanf("%d", &d);
	e = del(d, e);//此处传递的指针会变,所以不用p
	if (e != NULL)
	{
		printf("删除后的二叉树为:");
		print(f);
	}
	else
		printf("不存在该节点,删除失败!\n");
	
	system("pause");
	return 0;
}

二叉查找树(Binary Search Tree, BST),也有称作二叉排序树,二叉检索树,二叉搜索树,检索树 等等。其数据结构表示和二叉树相同,在此基础之上还有其特殊的性质,递归定义为:

一颗非空的二叉查找树(Binary Search Tree, BST),满足如下特性:

  • 若根节点的左子树非空,则左子树所有节点数值小于根节点;
  • 若根节点的右子树非空,则右子树所有节点数值大于根节点;
  • 左右子树分别为一颗二叉查找树.

删除说明:如果没有子节点,那最简单直接删除,如果有一个子节点,就把子节点代替删除的那个节点的位置,如果有两个子节点,就需要遍历右子树,找出最小的,代替它。

由于左边肯定小一些,所以只需要遍历以待删除的节点为根节点的树的左子树。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值