C++ : 二叉搜索树

1. 二叉搜索树概念

二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:

若它的左子树不为空,则左子树上所有节点的值都小于根节点的值

若它的右子树不为空,则右子树上所有节点的值都大于根节点的值

它的左右子树也分别为二叉搜索树

2 .二叉搜索树操作及其实现

                                        

int a[] = {8, 3, 1, 10, 6, 4, 7, 14, 13};

1. 二叉搜索树的查找

a、从根开始比较,查找,比根大则往右边走查找,比根小则往左边走查找。

b、最多查找高度次,走到到空,还没找到,这个值不存在。

bool Find(const K& key)
	{
		Node* cur = _root;
		while (cur)
		{
			if (key > cur->key)
			{
				cur = cur->right;
			}
			else if (key < cur->key)
			{
				cur = cur->left;
			}
			else
			{
				return true;
			}
		}
		return false;
	}

2. 二叉搜索树的插入

插入的具体过程如下:

a. 树为空,则直接新增节点,赋值给root指针

b. 树不空,按二叉搜索树性质查找插入位置,插入新节点

bool Insert(const K& key)
	{
		if (_root == nullptr)
		{
			_root = new Node(key);
			return true;
		}
		Node* cur = _root;
		Node* parent = nullptr;
		while (cur)
		{
			if (key > cur->key)
			{
				parent = cur;
				cur = cur->right;
			}
			else if (key < cur->key)
			{
				parent = cur;
				cur = cur->left;
			}
			else
			{
				return false;
			}
		}
		cur = new Node(key);
        //此时cur已经存放了新节点的地址,需要重新与cur链接
		if (key > parent->key)
		{
			parent->right = cur;
		}
		else
		{
			parent->left = cur;
		}
		return true;
	}

3.搜索二叉树的中序遍历

void InOrder()
	{
		_InOrder(_root);
	}
private:
	void _InOrder(Node* root)
	{
		if (root == nullptr)
		{
			return;
		}
		_InOrder(root->left);
		cout << root->key<< " " ;
		_InOrder(root->right);
 	}

4.搜索二叉搜索树的删除

首先查找元素是否在二叉搜索树中,如果不存在,则返回, 否则要删除的结点可能分下面四种情 况:

a. 要删除的结点无孩子结点

b. 要删除的结点只有左孩子结点

c. 要删除的结点只有右孩子结点 d. 要删除的结点有左、右孩子结点

看起来有待删除节点有4中情况,实际情况a可以与情况b或者c合并起来,因此真正的删除过程 如下:

bool Erase(const K& key)
	{
		if (_root == nullptr)
		{
			return false;
		}
		Node* cur = _root;
		Node* parent = nullptr;
		while (cur)
		{
			if (key > cur->key)
			{
				parent = cur;
				cur = cur->right;
			}
			else if (key < cur->key)
			{
				parent = cur;
				cur = cur->left;
			}
			else
			{
				if (cur->left == nullptr)
				{
					if (parent == nullptr)
					{
						_root = cur->right;
					}
					else
					{
						if (key > parent->key)
						{
							parent->right = cur->right;
						}
						else if (key < parent->key)
						{
							parent->left = cur->right;
						}
					}
					delete cur;
					return true;
				}
				else if (cur->right == nullptr)
				{
					if (parent == nullptr)
					{
						_root = cur->left;
					}
					else
					{
						if (key > parent->key)
						{
							parent->right = cur->left;
						}
						else if (parent->key < cur->key)
						{
							parent->left = cur->left;
						}
					}
					delete cur;
					return true;
				}
				else
				{
					//找右侧最小
						
						Node* r = cur;
						cur = cur->right;
						while (cur->left)
						{
							parent = cur;
							cur = cur->left;
						}
						r->key = cur->key;
						if (cur == r->right)
						{
							r->right = cur->right;
						}
						else
						{
							parent->left = cur->right;
						}
						delete cur;
						return true;
				}
			}

		}
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值