【数据结构】二叉搜索树

二叉搜索树的性质:
  1. 每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不相同。
  2. 左子树上所有节点的关键码(key)都小于根节点的关键码(key)。
  3. 右子树上所有节点的关键码(key)都大于根节点的关键码(key)。
  4. 左右子树都是二叉搜索树。
    //BSTree.h
    
    #pragma once 
    
    template<class K,class V>
    struct BSTreeNode
    {
    	BSTreeNode(const K& key,const V& value)
    		:_key(key),_value(value),_left(NULL),_right(NULL)
    	{}
    
    	K _key;
    	V _value;
    	BSTreeNode<K,V>* _left;
    	BSTreeNode<K,V>* _right;
    };
    
    template<class K,class V>
    class BSTree
    {
    	typedef BSTreeNode<K,V> Node;
    public:
    	BSTree()
    		:_root(NULL)
    	{}
    	bool Insert(const K& key,const V& value)
    	{
    		if(_root == NULL)
    		{
    			_root = new Node(key,value);
    		}
    		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;
    		}
    		cur =  new Node(key,value);
    		if(parent->_key < key)
    		{
    			parent->_right = cur;
    		}
    		else
    		{
    			parent->_left = cur;
    		}
    		return true;
    	}
    
    	Node* 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
    			{
    				cout<<cur->_key<<":"<<cur->_value<<endl;
    				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->_left;
    			}
    			else if(cur->_key < key)
    			{
    				parent = cur;
    				cur =  cur->_right;
    			}
    			else
    			{
    				break;
    			}
    		}
    		Node* del = NULL;
    		//1.要删除节点的左孩子或者右孩子为空
    		if(cur->_left == NULL)
    		{
    			del = cur;
    			if(parent->_left == cur)
    			{
    				parent->_left = cur->_right;
    			}
    			else
    			{
    				parent->_right = cur->_right;
    			}
    			delete del;
    		}
    		//删除节点的右孩子为空
    		else if(cur->_right == NULL) 
    		{
    			del = cur;
    			if(parent->_left == cur)
    			{
    				parent->_left = cur->_left;
    			}
    			else
    			{
    				parent->_right = cur->_left;
    			}
    			delete del;
    		}
    		// //找以该节点为根节点的左边(最大的)最右的孩子代替它,然后删除
    		else		//要删除节点的左右孩子都不为空
    		{
    			parent = cur;
    			//找以该节点为根节点的右边(最小的)最左的孩子代替它,然后删除
    			Node* subLeft = cur->_right;
    			while(subLeft->_left)
    			{
    				parent = subLeft;
    				subLeft =  subLeft->_left;
    			}
    			cur->_key = subLeft->_key;
    			cur->_value = subLeft->_value;
    
    			if(parent->_left == subLeft)
    				parent->_left = subLeft->_right;
    			else
    				parent->_right = subLeft->_right;
    			delete subLeft;
    		}
    		return false;
    	}
    
    	//递归插入
    	bool InsertR(const K& key,const V& value)
    	{
    		return _InsertR(_root,key,value);
    	}
    	//递归删除
    	bool RemoveR(const K& key)
    	{
    		return _RemoveR(_root,key);	
    	}
    	//递归查找
    	Node* FindR(const K& key)
    	{
    		return _FindR(_root,key);
    	}
    
    	void InOrder()
    	{
    		_InOrder(_root);
    		cout<<endl;
    	}
    protected:
    	bool _InsertR(Node*& root,const K& key,const V& value)
    	{	
    		if(root == NULL)
    		{
    			root = new Node(key,value);
    			return true;
    		}
    		if(root->_key > key)
    		{
    			return _InsertR(root->_left,value);
    		}
    		else if(root->_key < key)
    		{
    			return _InsertR(root->_right,value);
    		}
    		else
    		{
    			return false;			
    		}
    	}
    	//递归的删除一个节点
    	bool _RemoveR(Node*& root,const K& key)
    	{
    		if(root == NULL)
    		{
    			return false;
    		}
    		if(root->_key < key)
    		{
    			_RemoveR(root->_right,key);
    		}
    		else if(root->_key > key)
    		{
    			_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* subLeft = root->_right;
    				while(subLeft->_left)
    				{
    					subLeft = subLeft->_left;
    				}
    				swap(root->_key,subLeft->_key);
    				swap(root->_value,subLeft->_value);
    				return _RemoveR(root->_right,key);
    			}
    			delete del;
    		}
    		return true;
    	}
    
    	Node* _FindR(Node*& root,const K& key)
    	{
    		if(_root == NULL)
    		{
    			return NULL;
    		}
    		if(root->_key > key)
    		{
    			_FindR(root->_left,key);
    		}
    		else if(root->_key < key)
    		{
    			_FindR(root->_right,key);
    		}
    		else
    		{
    			cout<<root->_key<<":"<<root->_value<<endl;
    			return root;
    		}
    		return NULL;
    	}
    
    	void _InOrder(Node* root)
    	{
    		if(root == NULL)
    		{
    			return;
    		}
    		_InOrder(root->_left);
    		cout<<root->_key<<" ";
    		_InOrder(root->_right);	
    	}
    protected:
    	Node* _root;
    };
    
    //测试迭代
    void TestTree()
    {
    	BSTree<int,int> bst;
    	int a[] = {5,3,7,1,4,6,8,2,9};
    	for(size_t i = 0; i < sizeof(a)/sizeof(a[0]); i++)
    	{
    		bst.Insert(a[i],i);
    	}
    	bst.InOrder();
    	BSTreeNode<int,int>* ret = bst.Find(6);
    	bst.Remove(9);
    	bst.InOrder();
    	bst.Remove(7);
    	bst.InOrder();
    	bst.Remove(5);
    	bst.InOrder();
    	bst.Remove(3);
    	bst.InOrder();
    }
    
    //测试递归
    void TestTreeR()
    {
    	BSTree<int,int> bst1;
    	int a1[] = {5,9};
    	for(size_t i = 0; i < sizeof(a1)/sizeof(a1[0]); i++)
    	{
    		bst1.InsertR(a1[i],i);
    	}
    	bst1.InOrder();
    	BSTreeNode<int,int>* ret1 = bst1.FindR(6);
    	bst1.RemoveR(9);
    	bst1.InOrder();
    	bst1.RemoveR(5);
    	bst1.InOrder();
    	bst1.RemoveR(3);
    	bst1.InOrder();
    	bst1.RemoveR(7);
    	bst1.InOrder();
    	bst1.RemoveR(8);
    	bst1.InOrder();
    	bst1.RemoveR(2);
    	bst1.InOrder();
    	bst1.RemoveR(6);
    	bst1.InOrder();
    }

    //Test.cpp
    
    #include<iostream>
    using namespace std;
    #include"BSTree.h"
    
    int main()
    {
    	//TestTree();
    	TestTreeR();
    	getchar();
    	return 0;
    }

相关文章

【啊哈!算法】算法3:最常用的排序——快速排序       ...
匿名组 这里可能用到几个不同的分组构造。通过括号内围绕的正...
选择排序:从数组的起始位置处开始,把第一个元素与数组中其...
public struct Pqitem { public int priority; ...
在编写正则表达式的时候,经常会向要向正则表达式添加数量型...
来自:http://blog.csdn.net/morewindows/article/details/6...