Bootstrap

二叉搜索树(Binary Search Tree)

二叉搜索树概念

二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:

若它的左子树不为空,则左子树上所有节点的值都小于根节点的值

若它的右子树不为空,则右子树上所有节点的值都大于根节点的值

它的左右子树也分别为二叉搜索树

二叉搜索树操作

1. 二叉搜索树的查找

a、从根开始比较,查找,比根大则往右边走查找,比根小则往左边走查找。

b、最多查找高度次,走到到空,还没找到,这个值不存在。

2. 二叉搜索树的插入 插入的具体过程如下:

a. 树为空,则直接新增节点,赋值给root指针

b. 树不空,按二叉搜索树性质查找插入位置,插入新节点

3. 二叉搜索树的删除

首先查找元素是否在二叉搜索树中,如果不存在,则返回, 否则要删除的结点可能分下面四种情 况:

a. 要删除的结点无孩子结点

b. 要删除的结点只有左孩子结点

c. 要删除的结点只有右孩子结点

d. 要删除的结点有左、右孩子结点

看起来有待删除节点有4种情况,实际情况a可以与情况b或者c合并起来,因此真正的删除过程 如下:

情况b:删除该结点且使被删除节点的双亲结点指向被删除节点的左孩子结点--直接删除

情况c:删除该结点且使被删除节点的双亲结点指向被删除结点的右孩子结点--直接删除

情况d:在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被删除节点 中,再来处理该结点的删除问题--替换法删除

搜索二叉树(包括递归版和非递归版)

#pragma once
#include<iostream>
#include<string>
using namespace std;

//搜索二叉树节点
template<class K>
struct BSTreeNode
{
	BSTreeNode* left;
	BSTreeNode* right;
	K key;

	BSTreeNode(const K& k)
		:left(nullptr)
		, right(nullptr)
		, key(k)
	{}
};


namespace K
{
	template<class K>
	class BSTree
	{
	public:
		typedef BSTreeNode<K> node;
		
		BSTree()
		{}

		BSTree(const BSTree<K>& x)
		{
			_root = copy(x._root);
		}

		BSTree<K>& operator=(BSTree<K> x)
		{
			swap(_root, x._root);
			return *this;
		}

		~BSTree()
		{
			destroy(_root);
			_root = nullptr;
		}


		bool insert(const K& k)
		{
			if (_root == nullptr)
			{
				node* newnode = new node(k);
				_root = newnode;
				return true;
			}

			node* parent = nullptr;
			node* cur = _root;
			while (cur)
			{
				if (cur->key == k)
				{
					return false;
				}
				else if (cur->key > k)
				{
					parent = cur;
					cur = cur->left;
				}
				else if (cur->key < k)
				{
					parent = cur;
					cur = cur->right;
				}
			}
			node* newnode = new node(k);
			if (parent->key > k)
			{
				parent->left = newnode;
			}
			else if (parent->key < k)
			{
				parent->right = newnode;
			}
			return true;
		}

		node* find(const K& k)
		{
			node* cur = _root;
			while (cur)
			{
				if (k == cur->key)
				{
					return cur;
				}
				else if (k < cur->key)
				{
					cur = cur->left;
				}
				else if (k > cur->key)
				{
					cur = cur->right;
				}
			}

			return nullptr;
		}

		void inorder()
		{
			_inorder(_root);
			cout << endl;
		}

		bool erase(const K& k)
		{
			node* parent = nullptr;
			node* cur = _root;
			while (cur)
			{
				if (k == cur->key)
				{
					break;
				}
				else if (k < cur->key)
				{
					parent = cur;
					cur = cur->left;
				}
				else if (k > cur->key)
				{
					parent = cur;
					cur = cur->right;
				}
			}
			if (cur == nullptr)
			{
				return false;
			}

			if (cur->left == nullptr)
			{
				if (parent == nullptr)
				{
					delete cur;
					_root = nullptr;
				}
				else if(k < parent->key)
				{
					parent->left = cur->right;
					delete cur;
				}
				else if (k > parent->key)
				{
					parent->right = cur->right;
					delete cur;
				}
			}
			else if (cur->right == nullptr)
			{
				if (parent == nullptr)
				{
					delete cur;
					_root = nullptr;
				}
				else if (k < parent->key)
				{
					parent->left = cur->left;
					delete cur;
				}
				else if (k > parent->key)
				{
					parent->right = cur->left;
					delete cur;
				}
			}
			else
			{
				node* pre = cur;
				node* right_min = cur->right;
				while (right_min->left)
				{
					pre = right_min;
					right_min = right_min->left;
				}
				swap(cur->key, right_min->key);
				if (pre == cur)
				{
					pre->right = right_min->right;
				}
				else
				{
					pre->left = right_min->right;
				}
				delete right_min;

			}
			return true;
		}

		///
		//递归版本
		bool insertR(const K& k)
		{
			return _insertR(_root, k);
		}

		node* findR(const K& k)
		{
			return _findR(_root, k);
		}

		bool eraseR(const K& k)
		{
			return _eraseR(_root, k);
		}


	protected:
		void _inorder(const node* n)
		{
			if (n == nullptr)
				return;

			_inorder(n->left);
			cout << n->key << "  ";
			_inorder(n->right);
		}

		node* copy(node* root)
		{
			if (root == nullptr)
			{
				return nullptr;
			}

			node* newnode = new node(root->key);
			newnode->left = copy(root->left);
			newnode->right = copy(root->right);
			return newnode;
		}

		void destroy(node* root)
		{
			if (root == nullptr)
			{
				return;
			}
			destroy(root->left);
			destroy(root->right);
			delete root;
		}

		bool _insertR(node*& root, const K& k)
		{
			if (root == nullptr)
			{
				root = new node(k);
				return true;
			}
			else if (k == root->key)
			{
				return false;
			}
			else if (k < root->key)
			{
				return _insertR(root->left, k);
			}
			else
			{
				return _insertR(root->right, k);
			}
		}

		node* _findR(node* root,const K& k)
		{
			if (root == nullptr)
			{
				return nullptr;
			}
			if (k == root->key)
			{
				return root;
			}
			else if (k < root->key)
			{
				return _findR(root->left, k);
			}
			else
			{
				return _findR(root->right, k);
			}
		}

		bool _eraseR(node*& root,const K& k)
		{
			if (root == nullptr)
			{
				return false;
			}
			if (k < root->key)
			{
				return _eraseR(root->left, k);
			}
			else if (k > root->key)
			{
				return _eraseR(root->right, k);
			}
			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* minRight = root->right;
					while (minRight->left)
					{
						minRight = minRight->left;
					}
					swap(root->key, minRight->key);
					return _eraseR(root->right, k);
				}
				return true;
			}
		}

		node* _root = nullptr;
	};

}

搜索二叉树(KV版)

namespace KV
{

	template<class K, class V>
	struct BSTreeNode
	{
		BSTreeNode* left;
		BSTreeNode* right;
		K key;
		V val;

		BSTreeNode(const K& k, const V& v)
			:left(nullptr)
			, right(nullptr)
			, key(k)
			, val(v)
		{}
	};

	template<class K, class V>
	class BSTree
	{
	public:
		typedef BSTreeNode<K, V> node;

		BSTree()
		{}

		BSTree(const BSTree<K, V>& x)
		{
			_root = copy(x._root);
		}

		BSTree<K, V>& operator=(BSTree<K, V> x)
		{
			swap(_root, x._root);
			return *this;
		}

		~BSTree()
		{
			destroy(_root);
			_root = nullptr;
		}


		bool insert(const K& k,const V& v)
		{
			if (_root == nullptr)
			{
				node* newnode = new node(k, v);
				_root = newnode;
				return true;
			}

			node* parent = nullptr;
			node* cur = _root;
			while (cur)
			{
				if (cur->key == k)
				{
					return false;
				}
				else if (cur->key > k)
				{
					parent = cur;
					cur = cur->left;
				}
				else if (cur->key < k)
				{
					parent = cur;
					cur = cur->right;
				}
			}
			node* newnode = new node(k, v);
			if (parent->key > k)
			{
				parent->left = newnode;
			}
			else if (parent->key < k)
			{
				parent->right = newnode;
			}
			return true;
		}


		void inorder()
		{
			_inorder(_root);
			cout << endl;
		}

		bool erase(const K& k)
		{
			node* parent = nullptr;
			node* cur = _root;
			while (cur)
			{
				if (k == cur->key)
				{
					break;
				}
				else if (k < cur->key)
				{
					parent = cur;
					cur = cur->left;
				}
				else if (k > cur->key)
				{
					parent = cur;
					cur = cur->right;
				}
			}
			if (cur == nullptr)
			{
				return false;
			}

			if (cur->left == nullptr)
			{
				if (parent == nullptr)
				{
					delete cur;
					_root = nullptr;
				}
				else if (k < parent->key)
				{
					parent->left = cur->right;
					delete cur;
				}
				else if (k > parent->key)
				{
					parent->right = cur->right;
					delete cur;
				}
			}
			else if (cur->right == nullptr)
			{
				if (parent == nullptr)
				{
					delete cur;
					_root = nullptr;
				}
				else if (k < parent->key)
				{
					parent->left = cur->left;
					delete cur;
				}
				else if (k > parent->key)
				{
					parent->right = cur->left;
					delete cur;
				}
			}
			else
			{
				node* pre = cur;
				node* right_min = cur->right;
				while (right_min->left)
				{
					pre = right_min;
					right_min = right_min->left;
				}
				swap(cur->key, right_min->key);
				swap(cur->val, right_min->val);
				if (pre == cur)
				{
					pre->right = right_min->right;
				}
				else
				{
					pre->left = right_min->right;
				}
				delete right_min;

			}
			return true;
		}

		node* Find(const K& k)
		{
			node* cur = _root;
			while (cur)
			{
				if (cur->key < k)
				{
					cur = cur->right;
				}
				else if (cur->key > k)
				{
					cur = cur->left;
				}
				else
				{
					return cur;
				}
			}

			return nullptr;
		}

	protected:
		void _inorder(const node* n)
		{
			if (n == nullptr)
				return;

			_inorder(n->left);
			cout << n->key << "  " << n->val << "  ";
			_inorder(n->right);
		}

		node* copy(node* root)
		{
			if (root == nullptr)
			{
				return nullptr;
			}

			node* newnode = new node(root->key,root->val);
			newnode->left = copy(root->left);
			newnode->right = copy(root->right);
			return newnode;
		}

		void destroy(node* root)
		{
			if (root == nullptr)
			{
				return;
			}
			destroy(root->left);
			destroy(root->right);
			delete root;
		}

		
		node* _root = nullptr;
	};

}

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;