码迷,mamicode.com
首页 > 其他好文 > 详细

搜索二叉树

时间:2016-07-17 18:09:11      阅读:253      评论:0      收藏:0      [点我收藏+]

标签:搜索二叉树

 二叉查找树(BinarySearch Tree,也叫二叉搜索树,或称二叉排序树Binary Sort Tree)或者是一棵空树,或具有如下性质:

  1. 每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不相同。

  2. 左子树上所有节点的关键码(key)都小于根节点的关键码(key)。

  3. 右子树上所有节点的关键码(key)都大于根节点的关键码(key)。

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

二叉搜索树相关操作:

(1)插入:新节点

    在二叉查找树中插入新结点,要保证插入新结点后仍能满足二叉查找树的性质。插入过程如下:

    a、若二叉查找树root为空,则使新结点为根;

    b、若二叉查找树root不为空,则查找该节点应插入的位置。若新结点的关键字小于插入点的关键字,则将新结点插入到插入点的左子树中,大于则插入到插入点的右子树中。否则,不插入,返回失败。 

 (2)查找:关键码的节点

    a.从根节点开始查找,若关键字小于目前节点的关键字,则到目前节点的左子树中查询;若关键字大于目前节点的关键字,则到目前节点的右子树中查询;否则,查找成功,返回当前节点。

    b.若到空还没找到,则查找失败。

 (3)、删除

    删除某个结点后依然要保持二叉查找树的特性。删除过程如下:

    a、若删除点是叶子结点,则设置其双亲结点的对应指针为空。

    b、若删除点只有左子树,或只有右子树,则设置其双亲结点的指针指向左子树或右子树。

    c、若删除点的左右子树均不为空,则:采用替代删除法

        1)查询删除点的右子树中的非空最小节点(即最左节点),交换要删除节点与右最小节点的关键码与值,删除右最小节点。

        或

        2)查询删除点的左子树中的非空最大节点(即最右节点),交换要删除节点与左最大节点的关键码与值,删除左最大节点。

注:中序遍历二叉查找树可得到一个关键字的有序序列。

#include<iostream>
using namespace std;
//搜索二叉树
template<class K,class V>
struct BSTreeNode
{
	K _key;
	V _val;
	BSTreeNode<K,V>* _left;
	BSTreeNode<K,V>* _right;
	BSTreeNode(K& key,V& val)
		:_key(key)
		, _val(val)
		, _left(NULL)
		, _right(NULL)
	{}
};
template<class K,class V>
class BSTree
{
	typedef BSTreeNode<K, V> Node;
public:
	BSTree()
		:_root(NULL)
	{}
	~BSTree()
	{
		_Destroy(_root);
		_root = NULL;
	}
	bool Insert(K& key, V& val)
	{
		if (_root == NULL)
		{
			_root = new Node(key, val);
			return true;
		}
		else
		{
			Node* parent = NULL;
			Node* cur = _root;
			while (cur)
			{
				if (cur->_key > key)
				{
					parent = cur;
					cur = cur->_left;
				}
				else if (cur->_key < key)
				{
					parent = cur;
					cur = cur->_right;
				}
				else
				{
					return false;
				}
			}
			cur = new Node(key, val);
			if (parent->_key < key)
			{
				parent->_right = cur;
			}
			else
			{
				parent->_left = cur;
			}
			return true;
		}
	}
	Node* Find(const K& key)
	{
		if (_root == NULL)
			return NULL;
		Node* cur = _root;
		while (cur)
		{
			if (cur->_key < key)
				cur = cur->_right;
			else if (cur->_key>key)
				cur = cur->_left;
			else
				return cur;
		}
		return NULL;
	}
	bool Remove(const K& key)
	{
		if (_root == NULL)
			return false;
		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
			{
				Node* del = NULL;
				if (cur->_left == NULL)
				{
					del = cur;
					if (cur == _root)
					{
						_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 (cur == _root)
					{
						_root = cur->_left;
					}
					else
					{
						if (parent->_left == cur)
						{
							parent->_left = cur->_left;
						}
						else
						{
							parent->_right = cur->_left;
						}
					}
				}
				else//左右都不为空
				{
					Node* rightMin = cur->_right;
					parent = cur;
					while (rightMin->_left)
					{
						parent = rightMin;
						rightMin = rightMin->_left;
					}
					cur->_key = rightMin->_key;
					cur->_val = rightMin->_val;

					del=rightMin;
					if (parent->_left == rightMin)
						parent->_left = NULL;
					else
						parent->_right = NULL;
				}
				delete del;
				return true;
			}
		}
		return false;
	}
	void InOrder()
	{
		if (_root == NULL)
			return;
		_InOrder(_root);
		cout << endl;
	}
	bool InsertR(K& key, V& val)
	{
		return _InsertR(_root, key, val);
	}
	Node* FindR(const K& key)
	{
		return _FindR(_root, key);
	}
	bool RemoveR(K key)
	{
		return _RemoveR(_root, key);
	}
protected:
	void _Destroy(Node* root)
	{
		if (root == NULL)
			return;
		_Destroy(root->_left);
		_Destroy(root->_right);
		delete root;
	}
	bool _InsertR(Node*& root, K& key, V& val)
	{
		if (root == NULL)
		{
			root = new Node(key, val);
			return true;
		}
		if (root->_key > key)
			return _InsertR(root->_left, key, val);
		else if (root->_key < key)
			return _InsertR(root->_right, key, val);
		else
			return false;
	}
	Node* _FindR(Node* root, const K& key)
	{
		if (root == NULL)
			return NULL;
		if (root->_key < key)
			return _FindR(root->_right, key);
		else if (root->_key>key)
			return _FindR(root->_left, key);
		else
			return root;
	}
	bool _RemoveR(Node*& root, 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* rightMin = root->_right;
				Node* parent = root;
				while (rightMin->_left)
				{
					parent = rightMin;
					rightMin = rightMin->_left;
				}
				root->_key = rightMin->_key;
				root->_val = rightMin->_val;
				del = rightMin;
				if (parent->_left == rightMin)
					parent->_left = NULL;
				else
					parent->_right = NULL;
			}
			delete del;
			return true;
		}
	}
protected:
	void _InOrder(Node* root)
	{
		if (root == NULL)
			return;
		_InOrder(root->_left);
		cout << root->_key << " ";
		_InOrder(root->_right);
	}
private:
	Node* _root;
};
void Test1()
{
	int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 };
	BSTree<int, int> t;
	for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
	{
		t.Insert(a[i], i);
	}
	for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
	{
		cout<<"是否存在"<<a[i]<<"  "<<t.Find(a[i])->_key<<endl;
	}
	t.InOrder();
	cout << 5 << t.Remove(5) << endl;
	cout << 8 << t.Remove(8) << endl;
	cout << 2 << t.Remove(2) << endl;
	cout << 1 << t.Remove(1) << endl;
	cout << 3 << t.Remove(3) << endl;
	cout << 7 << t.Remove(7) << endl;
	t.InOrder();
}
void Test2()
{
	int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 };
	BSTree<int, int> t;
	for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
	{
		t.InsertR(a[i], i);
	}
	for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
	{
		cout << "是否存在" << a[i] << "  " << t.FindR(a[i])->_key << endl;
	}
	t.InOrder();
	cout << 5 << t.RemoveR(5) << endl;
	cout << 8 << t.RemoveR(8) << endl;
	cout << 2 << t.RemoveR(2) << endl;
	cout << 1 << t.RemoveR(1) << endl;
	cout << 3 << t.RemoveR(3) << endl;
	cout << 7 << t.RemoveR(7) << endl;
	cout << 9 << t.RemoveR(9) << endl;
	cout << 0 << t.RemoveR(0) << endl;
	cout << 4 << t.RemoveR(4) << endl;
	cout << 6 << t.RemoveR(6) << endl;

	cout << 5 << t.RemoveR(5) << endl;
	cout << 6 << t.RemoveR(6) << endl;
	t.InOrder();
}

#include"SBTree.h"
int main()
{
	//Test1();
	Test2();
	system("pause");
	return 0;
}

注:搜索树的缺陷是一定情况下会退化为单链表。如果插入顺序为1,2,3。则树的插入,查找,删除复杂度皆为O(n).

本文出自 “小止” 博客,请务必保留此出处http://10541556.blog.51cto.com/10531556/1827148

搜索二叉树

标签:搜索二叉树

原文地址:http://10541556.blog.51cto.com/10531556/1827148

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!