二叉搜索树的实现

首先我们先来看看二叉搜索树的性质:
1. 每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不相同。
2.
左子树上所有节点的关键码(key)都小于根节点的关键码(key)。
3.
右子树上所有节点的关键码(key)都大于根节点的关键码(key)。

4. 左右子树都是二叉搜索树。

首先来看看二叉搜索树的插入:


1:首先判断树是否为空,为空就new新节点,放入key。

2:从根开始遍历,找要插入的数是否已经存在,如果存在就返回false。

3:如果不存在相同节点,则new新的节点进行插入。

代码如下:

bool Insert(const K& key)
	{
		if (_root==NULL)
		{
			_root=new Node(key);
			return true;
		}
		Node* cur=_root;
		Node* parent=NULL;
		while (cur)
		{
			if (cur->_key < key)
			{
				parent=cur;
				cur=cur->_right;
			}
			else if (cur->_key > key)
			{
				parent=cur;
				cur=cur->_left;
			}
			else
				return false;
		}
          //不存在相同的key
		if(parent->_key < key)
		{
			parent->_right=new Node(key);
			return true;
		}
		else if(parent->_key > key)
		{
			parent->_left=new Node(key);
			return true;
		}
		else
			return false;

	}
下面是递归的实现方法:

bool InsertR(Node *& root , const K& key)
{
	if (root == NULL)
	{
		root = new Node(key);
		return true;
	}
	if (root->_key < key)
	{
		return InsertR(root->_right,key);
	}
	else if (root->_key > key)
	{
		return InsertR(root->_left,key);
	}
	else
		return false;
}

下来是搜索二叉树的查找:

给一个指针变量cur存放-root,让cur循环,判断cur的-key和你要找的key是否相等,如果相等就返回true,否侧返回false。

代码如下:

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

下面的查找的递归实现:

bool FindR(Node *& root , const K& key)
{
	if (root == NULL)
	{
		return false;
	}
	if (root->_key < key)
	{
		return FindR(root->_right,key)
	}
	else if (root->_key > key)
	{
		return FindR(root->_left,key)
	}
	else
		return true;
}

最后是二叉搜索树的删除:

首先我们要考虑以下这些情况:

  • 没有这个节点
  • 删除根节点
  • 删除左子树为空的节点
  • 删除右子树为空的节点
  • 删除左右子书都不为空的节点

如果没有这个节点就不删了,直接return;
删除的是左子树为空或者右子树为空的时候注意与root的关系,在进行删除;
如果左右子树都不为空,就需要运用交换删除的方法,就是将要删除的结点与他的左子树最大节点或者右子树最小节点交换,删除即可。
代码如下

<strong><span style="font-size:18px;">bool Remove(const K& key)
	{
		Node *cur = _root;
		Node *parent = NULL;
		Node *del = NULL;
		while (cur&&cur->_key!=key)
		{
			if (cur->_key < key)
			{

				parent = cur;
				cur = cur->_right;
			}
			else if (cur->_key>key)
			{
				parent = cur;
				cur = cur->_left;
			}
			else
			{
				break;
			}
		}
		if (cur == NULL)
		{
			return false;   
		}
		if (cur->_left == NULL)
		{

			del = cur;
			if (parent == NULL)
			{
				_root = cur->_right;
			}
			else
			{

				if (parent->_left == cur)
				{
					parent->_left = cur->_right;
				}
				else
				{
					parent->_right = cur->_right;
				}
			}
		}
		else if (cur->_right==NULL)
		{
			del = cur;
			if (parent == NULL)
			{
				cur = cur->_left;
			}
			else
			{
				if (parent->_left == cur)
				{
					parent->_left = cur->_left;
				}
				else
				{
					parent->_right = cur->_right;
				}
			}

		}
		else
		{
			Node *minright = cur->_right;
			while (minright->_left)
			{
				parent = minright;
				minright = minright->_left;
			}
			del = minright;
			cur->_key = minright->_key;


			if (parent->_left = minright)
				parent->_left = minright->_right;
			else
				parent->_right = minright->_right;
		}
		delete del;
		del = NULL;
		return true;
	}
</span></strong>

下面是递归实现:

bool _RemoveR(Node *&root , const K& key)
	{
		if (root ==NULL)
		{
			return false;
		}
		if (root->_key < key)
		{
			return _RemoveR(root->_right,key);
		}
		else if (root->_key > key)
		{
			return _RemoveR(root->_left,key);
		}
		else
		{
			Node* del=root;
			if (root->_left == NULL)
			{
				root = root->_right;
			}
			else if (root->_right == NULL)
			{
				root = root->_left;
			}
			else
			{
				Node* parent = root;
				Node * minright = root->_right;
				while (minright->_left)
				{
					parent = minright;
					minright = minright->_left;
				}
				root->_key = minright->_key;
//
				if (parent->_right == minright)
					parent->_right = minright->_right;
				else
					parent->_left = minright->_right;
				del = minright;
			}
			delete del;
			return true;
		}
		return false;
	}

好,到这里基本的函数实现就完成了。下面是源代码:

#include <iostream>
#pragma once;
using namespace std;

template <class K>
struct SearchBinaryTreeNode
{
	K _key;   //关键字
	//V _value;
	SearchBinaryTreeNode *_left;
	SearchBinaryTreeNode *_right;
	SearchBinaryTreeNode(const K& key)
		:_key(key)
		,_left(NULL)
		,_right(NULL)
	{}
};

template <class K>
class SearchBinaryTree
{
	typedef SearchBinaryTreeNode<K> Node;

public:
	SearchBinaryTree()
	{
		_root=NULL;
	}

	SearchBinaryTree(const SearchBinaryTree<K>& sbt)
	{
		_root=_Copy();
	}
	~SearchBinaryTree()
	{
		_Destroy(_root);
	}
	SearchBinaryTree<K>& operator=(const SearchBinaryTree<K> sbt)
	{
		if (this != &sbt)    //防止自赋值
		{
			SearchBinaryTree<K> tmp(sbt);
			std::swap(_root,tmp._root);
		}
		return *this;
	}

public:

	bool RemoveR(const K& key)
	{
		return _RemoveR(_root,key);
	}

	void InOrder()
	{
		_InOrder(_root);
		cout<<endl;
	}

	Node *_Copy(Node *root)
	{
		Node *cur=root;
		Node *proot=NULL;//proot是拷贝的新树的根结点
		if(cur)
		{
			proot=new Node(cur->_key);
			proot->_left=_Copy(cur->_left);
			proot->_right=_Copy(cur->_right);
		}
		return proot;
	}


	

	void _Destroy(Node *root)
	{
		if(root == NULL)
			return ;
		Node *cur=root;
		if(cur)
		{
			_Destroy(cur->_left);
			_Destroy(cur->_right);
			delete cur;
			cur=NULL;
		}
	}


	bool Insert(const K& key)
	{
		if (_root==NULL)
		{
			_root=new Node(key);
			return true;
		}
		Node* cur=_root;
		Node* parent=NULL;
		while (cur)
		{
			if (cur->_key < key)
			{
				parent=cur;
				cur=cur->_right;
			}
			else if (cur->_key > key)
			{
				parent=cur;
				cur=cur->_left;
			}
			else
				return false;
		}
          //不存在相同的key
		if(parent->_key < key)
		{
			parent->_right=new Node(key);
			return true;
		}
		else if(parent->_key > key)
		{
			parent->_left=new Node(key);
			return true;
		}
		else
			return false;

	}

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

	bool Remove(const K& key)
	{
		Node *cur = _root;
		Node *parent = NULL;
		Node *del = NULL;
		while (cur&&cur->_key!=key)
		{
			if (cur->_key < key)
			{

				parent = cur;
				cur = cur->_right;
			}
			else if (cur->_key>key)
			{
				parent = cur;
				cur = cur->_left;
			}
			else
			{
				break;
			}
		}
		if (cur == NULL)
		{
			return false;   
		}
		if (cur->_left == NULL)
		{

			del = cur;
			if (parent == NULL)
			{
				_root = cur->_right;
			}
			else
			{

				if (parent->_left == cur)
				{
					parent->_left = cur->_right;
				}
				else
				{
					parent->_right = cur->_right;
				}
			}
		}
		else if (cur->_right==NULL)
		{
			del = cur;
			if (parent == NULL)
			{
				cur = cur->_left;
			}
			else
			{
				if (parent->_left == cur)
				{
					parent->_left = cur->_left;
				}
				else
				{
					parent->_right = cur->_right;
				}
			}

		}
		else
		{
			Node *minright = cur->_right;
			while (minright->_left)
			{
				parent = minright;
				minright = minright->_left;
			}
			del = minright;
			cur->_key = minright->_key;


			if (parent->_left = minright)
				parent->_left = minright->_right;
			else
				parent->_right = minright->_right;
		}
		delete del;
		del = NULL;
		return true;
	}

bool InsertR(Node *& root , const K& key)
{
	if (root == NULL)
	{
		root = new Node(key);
		return true;
	}
	if (root->_key < key)
	{
		return InsertR(root->_right,key);
	}
	else if (root->_key > key)
	{
		return InsertR(root->_left,key);
	}
	else
		return false;
}

bool FindR(Node *& root , const K& key)
{
	if (root == NULL)
	{
		return false;
	}
	if (root->_key < key)
	{
		return FindR(root->_right,key)
	}
	else if (root->_key > key)
	{
		return FindR(root->_left,key)
	}
	else
		return true;
}



protected:
	void _InOrder(Node *root)
	{
		if(root == NULL)
			return ;
		_InOrder(root->_left);
		cout<<root->_key<<" ";
		_InOrder(root->_right);
	}

	bool _RemoveR(Node *&root , const K& key)
	{
		if (root ==NULL)
		{
			return false;
		}
		if (root->_key < key)
		{
			return _RemoveR(root->_right,key);
		}
		else if (root->_key > key)
		{
			return _RemoveR(root->_left,key);
		}
		else
		{
			Node* del=root;
			if (root->_left == NULL)
			{
				root = root->_right;
			}
			else if (root->_right == NULL)
			{
				root = root->_left;
			}
			else
			{
				Node* parent = root;
				Node * minright = root->_right;
				while (minright->_left)
				{
					parent = minright;
					minright = minright->_left;
				}
				root->_key = minright->_key;
//
				if (parent->_right == minright)
					parent->_right = minright->_right;
				else
					parent->_left = minright->_right;
				del = minright;
			}
			delete del;
			return true;
		}
		return false;
	}

protected:
	Node *_root;
};

void test()
{
	int arr[]={5,3,4,1,7,8,2,6,0,9};
	size_t size=sizeof(arr)/sizeof(arr[0]);
	SearchBinaryTree<int> sbt;
	for (size_t i=0;i<size;i++)
	{
		sbt.Insert(arr[i]);
	}
	sbt.InOrder();
	sbt.Insert(1);
	sbt.Insert(10);
	sbt.InOrder();
	cout<<sbt.Find(1)<<endl;
	cout<<sbt.Find(7)<<endl;
	cout<<sbt.Find(20)<<endl;
	sbt.Remove(0);
	sbt.Remove(1);
	sbt.Remove(2);
	sbt.Remove(3);
	sbt.Remove(4);
    sbt.Remove(5);
	sbt.InOrder();
	sbt.Remove(6);
	sbt.Remove(7);
	sbt.Remove(8);
	sbt.Remove(9);
	sbt.InOrder();
	sbt.Remove(10);
	sbt.InOrder();
}

int main()
{
	test();
	system("pause");
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值