搜索二叉树的简单实现

实现二叉树的插入,查找,删除,以及递归实现:

插入和查找很简单,把握一点,小的在树左,大的在树右,大树子树都遵循一样的规则,查找就更简单了:

主要看删除,删除有三种情况,看图:


在一下代码中详细有说明:

#pragma once

template<class K,class V>
struct SBTNode
{
	K key;
	V value;

	SBTNode<K, V> *_left;
	SBTNode<K, V> *_right;

	SBTNode(const K& key, const V& value)
		:key(key)
		, value(value)
		, _left(nullptr)
		, _right(nullptr)
	{}

};

template<class K, class V>
class SBTree
{
	typedef SBTNode<K, V> Node;
public:
	SBTree()
		:_root(nullptr)
	{}

	~SBTree()
	{}

public:
	//非递归插入
	bool Insert(const K& key,const V& value)
	{
		return _Insert(key,value);
	}

	bool _Insert(const K& key, const V& value)
	{
		if (_root == nullptr)
		{
			_root = new SBTNode<K, V>(key, value);
			return true;
		}

		SBTNode<K, V> *parent = nullptr; //指向cur 的前驱
		SBTNode<K, V> *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;
			}
		}

		if (parent->key < key)
		{
			SBTNode<K, V> *node = new SBTNode<K, V>(key, value);
			parent->_right = node;
			return true;
		}

		else if (parent->key > key)
		{
			SBTNode<K, V> *node = new SBTNode<K, V>(key, value);
			parent->_left = node;
			return true;
		}
		else
		{
			return false;
		}
	}

	//递归插入
	bool Insert_R(const K& key, const V& value)
	{
		return _Insert_R(_root,key,value);
	}

	bool _Insert_R(Node* root, const K& key, const V& value)
	{
		if (root == nullptr)
		{
			root = new Node(key, value);
			return true;
		}

		if (root->key > key)
		{
			return _Insert_R(root->_left, key, value);
		}
		else if (root->key < key)
		{
			return _Insert_R(root->_right,key,value);
		}
		else
		{
			cout << key << "存在" << endl;
			return false;
		}
	}

	//非递归查找节点
	SBTNode<K, V>* Find(const K& key)
	{
		if (_root == nullptr)
		{
			return nullptr;
		}

		SBTNode<K, V> *cur = _root;
		while (cur)
		{
			if (cur->key == key)
			{
				return cur;
			}
			else if (cur->key > key)
			{
				cur = cur->_left;
			}
			else if (cur->key < key)
			{
				cur = cur->_right;
			}
			else
			{
				return nullptr;
			}
		}
		return nullptr;
	}

	
	SBTNode<K, V>* Find_R(const K& key)
	{
		return _Find_R(_root,key);
	}

	//递归查找
	Node* _Find_R(Node* root, const K& key)
	{
		if (root == nullptr)
		{
			return nullptr;
		}

		Node* cur = root;
		if (cur->key == key)
		{
			return cur;
		}

		else if (cur->key > key)
		{
			_Find_R(cur->_left,key);
		}
		else if (cur->key < key)
		{
			_Find_R(cur->_right,key);
		}
		else
		{
			return nullptr;
		}
	}

	//非递归删除节点
	bool Remove(const K& key)
	{
		//1.root为空
		if (_root == nullptr)
		{
			return false;
		}

		else if (_root->_left == nullptr && _root->_right == nullptr)
		{
			delete _root;
			_root = nullptr;
			return true;
		}

		Node* parent = nullptr;
		Node* del = _root;
		
		//1.查找要删的数
		while (del)
		{
			if (del->key > key)
			{
				parent = del;
				del = del->_left;
			}
			else if (del->key < key)
			{
				parent = del;
				del = del->_right;
			}
			else
			{
				//2.是没有此数,或者找到此数
				break;
			}
		}

		//3.处理被删节点
		if (del)
		{
			//1.左树为空,右子树替换
			if (del->_left == nullptr)
			{
				if (del == _root)
				{
					_root = del->_right;
				}
				else
				{
					if (del == parent->_left)
						parent->_right = del->_right;
					else
						parent->_left = del->_right;
				}
			}

			//2.右树为空,左子树替换
			else if (del->_right == nullptr)
			{
				if (del == _root)
				{
					_root = del->_left;
				}
				else
				{
					if (del == parent->_left)
						parent->_left = del->_left;
					else
						parent->_right = del->_left;
				}
			}

			//3.左右子树都不为空的情况
			else
			{
				Node* subRight = del->_right;
				Node* firstInder = del->_right;
				//找右边节点中序遍历的第一个节点
				while (firstInder->_left)
				{
					parent = firstInder;
					firstInder = firstInder->_left;
				}

				//交换
				swap(firstInder->key,del->key);
				swap(firstInder->value,del->value);

				if (firstInder = parent->_left)
					parent->_left = firstInder->_right;
				else
					parent->_right = firstInder->_right;

				del = firstInder;
			}
			delete del;
		}
		else
		{
			cout << "没有这个数" << endl;
			return false;
		}
	}

	//递归删除节点
	bool Remove_R(const K& key)
	{
		return _Remove_R(_root,key);
	}

	bool _Remove_R(Node*& root, const K& key)
	{
		if (root == nullptr)
			return false;
		if (root->key > key)
		{
			return _Remove_R(root->_left,key);
		}
		else if (root->key < key)
		{
			return _Remove_R(root->_right,key);
		}
		else
		{
			Node* del = root;
			if (root->_left == nullptr)
			{
				root = root->_right;
				delete del;
			}
			else if (root->_right == nullptr)
			{
				root = root->_left;
				delete del;
			}
			else
			{
				Node* firstInder = root->_right;
				while (firstInder->_left)
				{
					firstInder = firstInder->_left;
				}

				swap(del->key,firstInder->key);
				swap(del->value, firstInder->value);

				_Remove_R(firstInder,key);
			}
		}
	}

	//中序遍历
	void InOrder(SBTNode<K, V>* root)
	{
		if (root == nullptr)
		{
			return; //递归结束出口
		}

		SBTNode<K, V> *cur = root;
		InOrder(cur->_left);
		cout << cur->key << " ";
		InOrder(cur->_right);
	}


public:
	SBTNode<K, V> *_root;
};


void Test()
{
	int a[] = {5,3,4,1,7,8,2,6,0,9};
	SBTree<int, int> s1;
	for (int i = 0; i < sizeof(a)/sizeof(int); ++i)
	{
		s1.Insert(a[i],a[i]);
	}
	s1.InOrder(s1._root);
	cout << endl;
	cout << s1.Find(9)->key << endl;
	cout << s1.Find_R(0)->key<< endl;

	s1.Remove(5);
	s1.Remove_R(9);
	s1.InOrder(s1._root);
}
代码测试通过,赐教!

posted @ 2016-05-23 11:03  云端止水  阅读(192)  评论(0编辑  收藏  举报