BSTree树的实现

来源:互联网 发布:centos7.2 nginx 配置 编辑:程序博客网 时间:2024/05/24 01:27

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

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

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

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

下面是关于二叉搜索树的实现,其中比较难以操作的就是删除操作。我们来分析一下删除操作都有哪几种情况:

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

1.要删除的结点无孩子结点,那么可直接进行删除。

2.要删除的结点只有左孩子结点,则删除该结点,让被删除结点的双亲结点指向被删除结点的左孩子。

3.要删除的结点只有右孩子结点,则删除该结点,让被删除结点的双亲结点指向被删除结点的有孩子。

4.要删除的结点有左右孩子结点,则在该结点的右子树中寻找关键码最小的结点,或在该结点的左子树中寻找关键码最大的结点,然后两值进行交换,然后删除该删除的结点。

如图:


代码如下:

#pragma once#include<iostream>using namespace std;template<class K,class V>struct BSTreeNode{BSTreeNode<K,V>* _pleft;BSTreeNode<K, V>* _pright;K _key;V _value;BSTreeNode(const K& key, const V& value):_key(key), _value(value), _pleft(NULL), _pright(NULL){}};template<class K,class V>class BSTree{typedef BSTreeNode<K,V> Node;public:BSTree(): _pRoot(NULL){}~BSTree(){}BSTree(const BSTree& bst){_pRoot = _Copy(bst);}BSTree<K, V>& operator=(const BSTree<K, V>& bst){if (this != bst){Node* tmp = _Copy(bst._pRoot);_pRoot = _Destroy(bst._pRoot);_pRoot = tmp;}return *this;}Node* Find(const K& key){return _Find(key);}bool Insert(const K& key, const V& value){return _Insert(key, value);}bool Remove(const K& key){//return _Remove(key);return _Remove_R(_pRoot, key);}void InOrder(){cout << "InOrder: ";_InOrder(_pRoot);cout << endl;}const K& GetMaxKey()const{while(_pRoot){_pRoot = _pRoot->_pleft;}return _pRoot->_key;}const K& GetMinKey()const{while (_pRoot){_pRoot = _pRoot->_pright;}return _pRoot->_key;}protected:bool _Insert(const K& key, const V& value){if (NULL == _pRoot){_pRoot = new Node(key, value);return true;}Node* pCur = _pRoot;Node* pParent = NULL;while (pCur){if (key < pCur->_key){pParent = pCur;pCur = pCur->_pleft;}else if (key>pCur->_key){pParent = pCur;pCur = pCur->_pright;}elsereturn false;}pCur = new Node(key, value);if (key < pParent->_key)pParent->_pleft = pCur;elsepParent->_pright = pCur;return true;}//_Insert递归bool _Insert_R(Node* pRoot, const K& key, const V& value){if (pRoot == NULL){pRoot = new Node(key, value);return true;}if (pRoot){if (pRoot->_key > key)return _Insert_R(pRoot->_pleft, key, value);if (pRoot->_key < key)return _Insert_R(pRoot->_pright, key, value);elsereturn false;}}Node* _Copy(const BSTree& bst){Node* newNode = NULL;if (_pRoot != NULL){Node newNode = new Node(bst._pRoot->_key, bst._pRoot->_value);newNode->_pleft = _Copy(bst._pRoot->_pleft);newNode->_prigth = _Copy(bst._pRoot->_pright);}return newNode;}Node* _Find(const K& key){Node* pCur = _pRoot;while (pCur){if (pCur->_key > key)pCur = pCur->_pleft;else if (pCur->_key < key)pCur = pCur->_pright;elsereturn pCur;}return NULL;}//_Find递归Node* _Find_R(Node* pRoot,const K& key){if (pRoot){if (pRoot->_key > key){return _Find_R(pRoot->_pleft, key);}if (pRoot->_key < key){return _Find_R(pRoot->_pright, key);}elsereturn pRoot;}return NULL;}void _InOrder(Node* pRoot){if (pRoot){_InOrder(pRoot->_pleft);cout << pRoot->_key << " ";_InOrder(pRoot->_pright);}}bool _Remove(const K&key){if (_pRoot == NULL){return false;}Node* del = _pRoot;Node* pParent = NULL;while (del){//找到待删除节点if (del->_key > key){pParent = del;del = del->_pleft;}else if (del->_key < key){pParent = del;del = del->_pright;}else{break;}}if (del){if (NULL == del->_pleft){if (del != _pRoot){if (pParent->_pright == del){pParent->_pright = del->_pright;}else{pParent->_pleft = del->_pright;}}else{_pRoot = del->_pright;}}else if (NULL == del->_pright){if (del != _pRoot){if (pParent->_pright == del){pParent->_pright = del->_pleft;}else{pParent->_pleft = del->_pleft;}}else{_pRoot = del->_pleft;}}else{//查找右子树中中序遍历的第一个节点,进行替换,然后删除Node* firstInOrder = del->_pright;Node* pParent = del;while (firstInOrder->_pleft){pParent = firstInOrder;firstInOrder=firstInOrder->_pleft;}std::swap(del->_key, firstInOrder->_key);std::swap(del->_value, firstInOrder->_value);if (pParent->_pleft ==firstInOrder ){pParent->_pleft = firstInOrder->_pright;}else{pParent->_pright = firstInOrder->_pright;}del=firstInOrder;}delete del;}else{return false;}return true;}//_Remove_R递归bool _Remove_R(Node* pRoot, const K& key){if (pRoot){if (pRoot->_key > key)return _Remove_R(pRoot->_pleft, key);if (pRoot->_key < key)return _Remove_R(pRoot->_pright, key);else{if (pRoot->_pleft == NULL){Node* del = pRoot;pRoot = pRoot->_pright;delete del;}else if (pRoot->_pright == NULL){Node* del = pRoot;pRoot = pRoot->_pleft;delete del;}else{Node* right = pRoot->_pright;while (right->_pleft){right = right->_pleft;}swap(pRoot->_key, right->_key);swap(pRoot->_value, right->_value);_Remove_R(pRoot->_pright, right->_key);}return true;}}return false;}private:Node* _pRoot;};

 下面是加入了迭代器的优化版本:

#pragma once#include <iostream>using namespace std;#include <assert.h>template<class K,class V>struct Node{Node(){}Node(const K& key,const V& value):_key(key),_value(value),_parent(NULL),_pLeft(NULL),_pRight(NULL){}K _key;V _value;Node<K,V>* _parent;Node<K,V>* _pLeft;Node<K,V>* _pRight;};//迭代器template<class K,class V,class Ref,class Ptr>class BstIterator{typedef Node<K,V> Node;typedef BstIterator<K,V,Ref,Ptr> Self;public:BstIterator():_pNode(NULL){}BstIterator(Node* pNode):_pNode(pNode){}BstIterator(const Self& s){_pNode=s._pNode;}Self& operator++(){Increase(_pNode);return *this;}Self operator++(int){Self tmp(*this);Increase(_pNode);return tmp;}Self& operator--(){Decrease(_pNode);return *this;}Self operator--(int){Self tmp(*this);Decrease(_pNode);return tmp;}Ref operator*(){return _pNode->_key;}Ptr operator->(){return _pNode;}bool operator!=(const Self& s){return (_pNode!=s._pNode);}bool operator==(const Self& s){return !(*this!=s);}private:void Increase(Node*& pNode){assert(pNode);if(pNode->_pRight){pNode=pNode->_pRight;while(pNode->_pLeft){pNode=pNode->_pLeft;}}else{Node* parent=pNode->_parent;while(pNode==parent->_pRight){pNode=parent;parent=pNode->_parent;}if(pNode->_pRight!=parent){pNode=parent;}}}void Decrease(Node*& pNode){assert(pNode);if(pNode->_pLeft){pNode=pNode->_pLeft;while(pNode->_pRight){pNode=pNode->_pRight;}}else{Node* parent=pNode->_parent;while(pNode==parent->_pLeft){pNode=parent;parent=pNode->_parent;}pNode=parent;}}private:Node* _pNode;};template<class K,class V>class BinarySearchTree{typedef Node<K,V> Node;typedef BstIterator<K,V,K,Node*> BstIterator;public:BinarySearchTree(){_pHead=new Node;_pHead->_pLeft=_pHead;_pHead->_pRight=_pHead;_pHead->_parent=NULL;}BinarySearchTree(const BinarySearchTree<K,V>& bst){Node* pRoot=GetRoot();pRoot=_CopyTree(bst._pHead);}BinarySearchTree<K, V>& operator=(const BinarySearchTree<K, V>& bst){if(this!=&bst){Node* pRoot=GetRoot();Destory(pRoot);pRoot=_CopyTree(bst._pHead);}return *this;}BstIterator Begin(){BstIterator it(MostLeft());return it;}BstIterator End(){BstIterator it(_pHead);return it;}~BinarySearchTree(){Node* pRoot=GetRoot();Destory(pRoot);delete _pHead;}Node* Find(const K& key){Node* pRoot=GetRoot();return _Find(pRoot,key);}bool Insert(const K& key, const V& value){return _Insert(_pHead,key,value);}bool Remove(const K& key){return _Remove(_pHead,key);}void InOrder(){Node* pRoot=GetRoot();cout<<"InOrder: ";_InOrder(pRoot);cout<<endl;}const K& GetMaxKey()const{Node* pcur=GetRoot();while(pcur->_pRight)pcur=pcur->_pRight;return pcur->_key;}const K& GetMinKey()const{Node* pcur=GetRoot();while(pcur->_pLeft)pcur=pcur->_pLeft;return pcur->_key;}//转换成有序双向链表Node* ToList(){Node* pRoot=GetRoot();Node* pre=NULL;_ToList(pRoot,pre);return MostLeft();}protected:void _ToList(Node* pRoot,Node*& pre){if(pRoot==NULL)return ;_ToList(pRoot->_pLeft,pre);pRoot->_pLeft=pre;if(pre)pre->_pRight=pRoot;pre=pRoot;_ToList(pRoot->_pRight,pre);}Node* GetRoot(){return _pHead->_parent;}Node* MostLeft(){Node* pRoot=GetRoot();if(pRoot==NULL)return NULL;while(pRoot->_pLeft){pRoot=pRoot->_pLeft;}return pRoot;}Node* MostRight(){Node* pRoot=GetRoot();if(pRoot==NULL)return NULL;while(pRoot->_pRight){pRoot=pRoot->_pRight;}return pRoot;}Node* _CopyTree(Node* pHead){Node* pRoot=GetRoot();if(pRoot==NULL)return NULL;Node* ptmp=new Node(pRoot->_key,pRoot->_value);ptmp->_pLeft=_CopyTree(pRoot->_pLeft);ptmp->_pRight=_CopyTree(pRoot->_pRight);return ptmp;}void Destory(Node*& pRoot){if(pRoot){Destory(pRoot->_pLeft);Destory(pRoot->_pRight);delete pRoot;}}Node* _Find(Node* pRoot,const K& key){if(pRoot==NULL)return NULL;while(pRoot){if(key<pRoot->_key){pRoot=pRoot->_pLeft;}else if(key>pRoot->_key){pRoot=pRoot->_pRight;}elsereturn pRoot;}return NULL;}bool _Insert(Node*& pHead,const K& key,const V& value){Node* pRoot=GetRoot();if(pRoot==NULL){pRoot=new Node(key,value);pRoot->_parent=pHead;pHead->_parent=pRoot;}else{Node* pcur=pRoot;Node* parent=NULL;while(pcur){if(pcur->_key==key)return false;else if(key<pcur->_key){parent=pcur;pcur=pcur->_pLeft;}else{parent=pcur;pcur=pcur->_pRight;}}pcur=new Node(key,value);pcur->_parent=parent;if(key<parent->_key)parent->_pLeft=pcur;elseparent->_pRight=pcur;}pHead->_pLeft=MostLeft();pHead->_pRight=MostRight();return true;}bool _Remove(Node*& pHead,const K& key){Node* pRoot=GetRoot();if(pRoot==NULL)return false;Node* pcur=pRoot;Node* parent=NULL;while(pcur){if(key<pcur->_key){parent=pcur;pcur=pcur->_pLeft;}else if(key>pcur->_key){parent=pcur;pcur=pcur->_pRight;}else{if(pcur->_pLeft==NULL){if(pcur==pRoot){pRoot=pcur->_pRight;pHead->_parent=pRoot;pRoot->_parent=pHead;}else if(pcur==parent->_pLeft){parent->_pLeft=pcur->_pRight;if(pcur->_pRight)pcur->_pRight->_parent=parent;}else{parent->_pRight=pcur->_pRight;if(pcur->_pRight)pcur->_pRight->_parent=parent;}}else if(pcur->_pRight==NULL){if(pcur==pRoot){pRoot=pcur->_pLeft;pHead->_parent=pRoot;pRoot->_parent=pHead;}else if(pcur==parent->_pLeft){parent->_pLeft=pcur->_pLeft;if(pcur->_pLeft)pcur->_pLeft->_parent=parent;}else{parent->_pRight=pcur->_pLeft;if(pcur->_pLeft)pcur->_pLeft->_parent=parent;}}else{Node* pDel=pcur;parent=pcur;pDel=pDel->_pRight;while(pDel->_pLeft){parent=pDel;pDel=pDel->_pLeft;}pcur->_key=pDel->_key;pcur->_value=pDel->_value;if(pDel==parent->_pLeft){parent->_pLeft=pDel->_pRight;}else{parent->_pLeft=pDel->_pRight;}if(pDel->_pRight)pDel->_pRight->_parent=parent;pcur=pDel;}delete pcur;pHead->_pLeft=MostLeft();pHead->_pRight=MostRight();return true;}}return false;}void _InOrder(Node* pRoot){if(pRoot){_InOrder(pRoot->_pLeft);cout<<pRoot->_key<<" ";_InOrder(pRoot->_pRight);}}private:Node* _pHead;};