二叉搜索树(二叉排序树,二叉查找树,二叉检索树)的查找,插入,删除

1,二叉搜索树定义?
(1)每个节点有一个唯一的key值,且所有结点互不相同;
(2)左子树所有key值小于根的key值;
(3)右子树所有key值大于根的key值;
(4)左右子树都是二叉搜索树。
这就是一棵二叉搜索树。
2,二叉搜索树的查找操作:
(1)与根结点的key值比较,相等则 查找成功;
(2)小于则查找左子树;
(3 大于则查找右子树。
3,二叉搜索树的插入操作:
(1)先用查找操作找到要插入元素插入后的父亲节点;
(2)和父亲比较大小后,决定作为右孩子还是左孩子插入;
(3)若树空,则作为根节点插入。
4,二叉搜索树的删除操作:
(1)先用查找操作找到被删除元素的位置;
(2)若被删除元素只有左孩子或者只有右孩子,则直接删除,把它的右孩子或左孩子加到它父亲上;
如图所示:
(3)若被删除元素两个孩子都有,选取“替身”取代被删结点。然后删除替身结点!
如何选择替身?
左子树中最大的结点(从被删点的左子树中找到最右边的那个点)或 右子树中最小的结点(从被删点的右子树中的找到最右边的点)都可以作为替换节点;找到后,和被删点交换数据,则问题变成了删除替换节点的问题了,而此时替换节点只有一个孩子,就回到了上述第二种情况了。
如图所示:
找到后,交换200和122,然后问题变成了删除叶子节点的问题了。
下边是具体代码:
#include "stdafx.h"
#include <iostream>
using std::cin;
using std::cout;
using std::endl;

typedef struct Bstnode{
	int data;
	Bstnode *rchild;
	Bstnode *lchild;
	Bstnode()
	{
		rchild = NULL;
		lchild = NULL;
	}
}*Bitree;
//下边是先序遍历建树的代码
void CreateBST(Bitree &T)//先序遍历建树
{
	int data;
	cin >> data;
	if (data == -1)
	{
		T = NULL;
	}
	else
	{
		T = new Bstnode;
		T->data = data;//在前面要申请空间,T是一个指针;
		CreateBST(T->lchild);
		CreateBST(T->rchild);
	}
}
//下边是在二叉搜索树中查找的代码
//f表示T的父亲节点,初始为空,p用来返回被查到的位置
//要是找到了,p为该元素在树中所在位置;
//要是没找到,p为插入该元素后的父亲节点所在位置;
bool SearchBST(Bitree T, int key, Bitree f, Bitree &p)
{
	if (!T)
	{
		p = f;
		return false;
	}
	else
	{
		if (T->data == key)
		{
			//cout << "已经存在了,不做插入!" << endl;
			p = T;
			return true;
		}
		else
			if (T->data < key)
			{
				return SearchBST(T->rchild, key, T, p);
			}
			else
				{
					return SearchBST(T->lchild, key, T, p);
				}
	}
}
//下边是在二叉搜索树中插入元素的代码
void InsertToCreateBST(Bitree &T, int data)
{
	if (!T)
	{
		T = new Bstnode;
		T->data = data;
	}
	else
	{
		Bitree f = NULL;
		Bitree p = NULL;
		SearchBST(T, data, f, p);//找到该元素的父亲节点
		Bitree s = new Bstnode;
		s->data = data;
		if(p->data < data)
		{
			p->rchild = s;
		}
		else
		{
			p->lchild = s;
		}
	}
}
//下边是在二叉搜索树中删除元素的代码
void DeleteBST(Bitree &T, int data)
{
	Bitree f = NULL;
	Bitree p = NULL;
	if (!SearchBST(T, data, f, p))
	{
		cout << "删除的元素不在树中!" << endl;
	}
	else
	{
		if (!p->rchild)
		{
			Bitree q = p;
			p = p->lchild;
			delete q;
		}
		else
			if (!p->lchild)
			{
				Bitree q = p;
				p = p->rchild;
				delete q;
			}
			else//这种情况是找替换点,这里我们找右子树中最小的数,找到后和被删节点替换数据删除即可
			{
				Bitree s = p;//指向右子树中最小节点的父亲节点,用来区分情况
				Bitree q = p->rchild;
				while (q->lchild)
				{
					s = q;
					q = q->lchild;//q指向被删节点右子树中最小的节点
				}
				//找到替换点了,交换数据
				p->data = q->data;
				if (s != p)//表明被删点的右孩子有左子树
				{
					s->lchild = q->rchild;
				}
				else//表明被删点的右孩子没有左子树,右孩子本身就是被替换点
				{
					p->rchild = q->rchild;
				}
				delete q;
			}
	}
}
void PrintBST(Bitree T)
{
	if (!T)
	{
		return;
	}
	else
	{
		cout << T->data <<' ';
		PrintBST(T->lchild);
		PrintBST(T->rchild);
	}
}
int _tmain(int argc, _TCHAR* argv[])
{
	Bitree T = NULL;
	//CreateBST(T);
	//PrintBST(T);
	//InsertToCreateBST(T, 4);
	int a[11] = {400,450,122,99,110,105,250,200,230,300,500};
	for (int i = 0; i < 11; i++)
	{
		InsertToCreateBST(T, a[i]);
	}
	PrintBST(T);
	cout << endl;
	cout << "删除一个顶点后为:" << endl;
	DeleteBST(T, 122);
	PrintBST(T);
	cout << endl;
	system("pause");
	return 0;
}
运行结果显示为:
5,二叉搜索树性质分析:
主要用于内存中目录的编制,要求能够快速的查找,插入和删除。
查找,插入和删除的时间代价都为O(h),h为树的高度。
但二叉搜索树的高度与插入顺序有关,例如:

这就引出了平衡二叉树的概念了。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值