天天看點

搜尋二叉樹

 二叉查找樹(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)查詢删除點的右子樹中的非空最小節點(即最左節點),交換要删除節點與右最小節點的關鍵碼與值,删除右最小節點。

        或

#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;
}      

繼續閱讀