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

搜索二叉树

时间:2016-07-20 19:47:38      阅读:165      评论:0      收藏:0      [点我收藏+]

标签:include   二叉树   元素   左右   

 

二叉搜索树所具有的性质:

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

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

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

每一个左右子树都必须是二叉搜索树。


二叉搜索树的插入规则:

      a.若当前的二叉查找树为空,则插入的元素为根节点       b.若插入的元素值小于根节点值,则将元素插入到左子树中       c.若插入的元素值不小于根节点值,则将元素插入到右子树中。        首先找到插入的位置,要么向左,要么向右,直到找到空结点,即为插入位置,        如果找到了相同值的结点,则直接返回

因为二叉搜索树的左节点值小于根节点,而根节点值小于右节点,因此可通过中序遍历对该树进行遍历,可得到一个有序序列

#include <iostream>
using namespace std;

template<class K,class V>
struct BSTreeNode
{
	
	BSTreeNode<K, V>* _left;
	BSTreeNode<K, V>* _right;
	K _key;
	V _value;
	BSTreeNode(const K& key, const V& value)
		:_left(NULL)
		, _right(NULL)
		, _key(key)
		, _value(value)
	{}
};

template<class K,class V>
class BSTree
{
	typedef BSTreeNode<K, V> Node;
public:
	BSTree()
		:_root(NULL)
	{}
	bool Insert(const K& key, const V& value)
	{
		return _Insert(_root,key, value);
	}
	bool Find(const K& key)
	{
		return _Find(_root, key);
	}
	bool Remove(const K& key)
	{
		return _Remove(_root,key);
	}

	void InOrder()
	{
		_InOrder(_root);
	}

	~BSTree()
	{}
protected:
	bool _Insert(Node*& root, const K& key, const V& value)
	{
		if (root == NULL)
		{
			root = new Node(key, value);
			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
			{
				cout << "已经存在该节点" << endl;
				return false;
			}
		}
		if (parent->_key < key)
			parent->_right = new Node(key, value);
		else if (parent->_key>key)
			parent->_left = new Node(key, value);
		return true;
	}

	bool _Find(Node* root, const K& key)
	{
		if (root == NULL)
			return false;
		Node* cur = root;
		while (cur)
		{
			if (cur->_key == key)
				return true;
			else if (cur->_key > key)
				cur = cur->_left;
			else
				cur = cur->_right;
		}
		cout <<key<<"该节点不存在" << endl;
		return false;
	}

	bool _Remove(Node*& root, const K& key)
	{
		if (root == NULL)
			return false;
		Node* cur = root;
		Node* del = NULL;
		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
			{
				//1.左子树为空
				if (cur->_left == NULL)
				{
					del = cur;
					if (parent == NULL || cur==root)
					{
						root = cur->_right;
					}
					else
					{
						if (parent->_left == cur)
							parent->_left = cur->_right;
						else if (parent->_right==cur)
							parent->_right = cur->_right;
					}
				}
				else if (cur->_right == NULL)//右子树为空
				{
					del = cur;
					if (parent == NULL || cur == root)
					{
						root = cur->_left;
					}
					else
					{
						if (parent->_left == cur)
							parent->_left = cur->_left;
						else
							parent->_right = cur->_left;
					}
				}
				else //左右都不为空
				{
					Node* left = cur->_left;
					while (left->_right)//找它的左子树上最右节点进行替换删除
					{
						parent = left;
						left = left->_right;
					}
					swap(cur->_key, left->_key);
					swap(cur->_value, left->_value);
					del = left;
					if (parent->_left == left)
						parent->_left = NULL;
					else
						parent->_right = NULL;
				}
				delete del;
				del = NULL;
				cout << key << "删除成功" << endl;
				return true;
				break;
			}
		}
	}
	void _InOrder(Node* root)
	{
		if (root == NULL)
			return;
		_InOrder(root->_left);
		cout << root->_key << " ";
		_InOrder(root->_right);

	}

protected:
	Node* _root;
};
void Test()
{
	BSTree<int, int> bt;
	int a[] = { 6, 5, 2, 8, 3, 9, 0, 1, 4, 10, 7 };
	for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
	{
		bt.Insert(a[i], i);
	}
	bt.InOrder();
	cout << endl;
	//cout << "节点是否存在?" << bt.Find(9) << endl;
	//cout << "节点是否存在?" << bt.Find(6) << endl;
	cout << "节点是否存在?" << bt.Find(1) << endl;
	cout << "节点是否存在?" << bt.Find(10) << endl;
	bt.Remove(5);
	bt.Remove(6);
	bt.Remove(1);
	bt.Remove(10);
	cout << "节点是否存在?" << bt.Find(1) << endl;
	cout << "节点是否存在?" << bt.Find(10) << endl;

	bt.InOrder();

}


搜索二叉树

标签:include   二叉树   元素   左右   

原文地址:http://10541559.blog.51cto.com/10531559/1828139

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