二叉搜索树---使用迭代器

来源:互联网 发布:qq软件下载安装 编辑:程序博客网 时间:2024/06/05 00:54

迭代器:它的用法与指针用法相同
使用迭代器实现二叉搜索树,使用有两个指针域的头结点实现,
并且多给BSTree中加入一个双亲结点_pParent。

这里写图片描述

代码:
BSTIterator.hpp

#pragma once#include<iostream>using namespace std;#include<assert.h>template<class k,class v>struct BSTNode{    BSTNode(const k& key=k(),const v& value=v())        :_pLeft(NULL)        ,_pRight(NULL)        ,_pParent(NULL)        ,_key(key)        ,_value(value)    {}    BSTNode<k,v>* _pLeft;    BSTNode<k,v>* _pRight;    BSTNode<k,v>* _pParent;    k _key;    v _value;};template<class K, class V, class Ref, class Ptr>class BSTIterator{    typedef BSTNode<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++()    {        Increment();        return *this;    }    Self operator++(int)    {        Self temp(*this);        Increment();        return temp;    }    Self& operator--()    {        Decrement();        return *this;    }    Self operator--(int)    {        Self temp(*this);        Decrement();        return temp;    }    Ref operator*()//解引用    {        return _pNode->_key;    }    Ptr operator->()//->    {        return &(operator*());    }    bool operator!=(const Self& s)    {        return _pNode!=s._pNode;    }    bool operator==(const Self& s)    {        return !(*this!=s);    }protected:    // 取当前结点的下一个结点    void Increment()    {        //如果右子树存在,右子树中的最小结点就是当前结点的下一个结点        if(_pNode->_pRight)        {            _pNode=_pNode->_pRight;            while(_pNode->_pLeft)                _pNode=_pNode->_pLeft;        }        else//右子树不存在        {            Node* pParent=_pNode->_pParent;            while(pParent->_pRight==_pNode)            {                _pNode=pParent;                pParent=pParent->_pParent;            }            //特殊情况:根的右子树不存在,获取根的下一节点即为end()            if(_pNode->_pRight!=pParent)                _pNode=pParent;        }    }    // --取前一个小的结点,在left子树中    void Decrement()    {        //左子树存在        if(_pNode->_pRight)        {            _pNode=_pNode->_pLeft;            while(_pNode->_pRight)                _pNode=_pNode->_pRight;        }        else        {            Node* pParent=_pNode->_pParent;            while(_pNode==pParent->_pLeft)            {                _pNode=pParent;                pParent=pParent->_pParent;            }            _pNode=pParent;        }    }protected:    Node* _pNode;};template<class k,class v>class BSTree{    typedef BSTNode<k,v> Node; public:    typedef BSTIterator<k,v,k&,k*> Iterator;public:    BSTree()    {        _pHead=new Node();        _pHead->_pLeft=_pHead;        _pHead->_pRight=_pHead;        _pHead->_pParent=NULL;    }    Iterator Begin()    {        return _pHead->_pLeft;    }    Iterator End()    {        return _pHead;    }    Node* Find(const k& key)    {        Node* pCur=GetRoot();        while(pCur)        {            if(key==pCur->_key)                return pCur;            else if(key<pCur->_key)                pCur=pCur->_pLeft;            else                pCur=pCur->_pRight;        }        return NULL;    }    bool Insert(const k& key,const v& value)    {        Node*& pRoot=_pHead->_pParent;        if(NULL==pRoot)        {            pRoot=new Node(key,value);            pRoot->_pParent=_pHead;        }        else        {            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;               }               else//等于根节点,不需要插入               {                   return false;               }           }           //插入到叶子结点后时           pCur=new Node(key,value);           if(key<pParent->_key)               pParent->_pLeft=pCur;           else               pParent->_pRight=pCur;           pCur->_pParent=pParent;        }        _pHead->_pLeft=LeftMost();        _pHead->_pRight=RightMost();        return true;    }    void InOrder()//中序遍历    {        cout<<"InOrder:"<<endl;        _InOrder(GetRoot());        cout<<endl;    }    const k& GetMaxKey()const//找最右结点(最大)    {        Node* pRoot=GetRoot();        assert(pRoot);        Node* pCur=pRoot;        while(pCur->_pRight)            pCur=pCur->_pRight;        return pCur->_key;    }    const k& GetMinKey()const//找最左结点(最小)    {        Node* pRoot=GetRoot();        assert(pRoot);        Node* pCur=pRoot;        while(pCur->_pLeft)            pCur=pCur->_pLeft;        return pCur->_key;    }    bool Remove(const k& key)//删除key结点    {        Node*& pRoot=GetRoot();        //树为空,不能删除结点        if(NULL==pRoot)            return false;        //只有一个根节点,要删除的结点正好是根节点        if(NULL==pRoot->_pLeft && NULL==pRoot->_pRight && key==pRoot->_key)        {                                                                                 delete pRoot;            _pHead->_pParent=NULL;        }        else        {            //找待删除结点            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;               }                       else                   break;//找到了该节点            }            //已找到待删除结点---》1.没有左孩子,只有右孩子                                 //2.没有右孩子,只有左孩子                                // 3.左右孩子都没有                                 //4.左右孩子都存在                                 //可以合并1,3 或2,3            if(NULL==pCur)                return false;            else            {   //1.没有左孩子,右孩子可能存在,也可能不存在(NULL)               if(NULL==pCur->_pLeft)               {                   if(pCur!=pRoot)                   {                       if(pCur==pParent->_pRight)                           pParent->_pRight=pCur->_pRight;                       else                           pParent->_pLeft=pCur->_pRight;                   }                   else                       pRoot=pCur->_pRight;                }            //2.没有右孩子,左孩子可能存在,也可能不存在(NULL)                else if(NULL==pCur->_pRight)               {                   if(pCur!=pRoot)                   {                       if(pCur==pParent->_pRight)                            pParent->_pRight=pCur->_pLeft;                       else                            pParent->_pLeft=pCur->_pLeft;                   }                   else                       pRoot=pCur->_pLeft;                }              //3.左右子树都存在                else               {                    //找中序遍历的第一个节点,为右子树中最小的结点                    //pParnet一直是firstInOrder的双亲                    pParent=pCur;//防止在找右子树中最小结点时,右子树没有左孩子,无法进入循环,pParent会一直为空                    Node* firstInOrder=pCur->_pRight;                   //找该节点的右子树中最左边的结点,即右子树中key最小的结点                    while(firstInOrder->_pLeft)                    {                        pParent=firstInOrder;                        firstInOrder=firstInOrder->_pLeft;                    }                //交换key最小结点和根节点的值                    pCur->_key=firstInOrder->_key;                    pCur->_value=firstInOrder->_value;                    if(pParent->_pLeft==firstInOrder)                        pParent->_pLeft=firstInOrder->_pRight;                    else                        pParent->_pRight=firstInOrder->_pRight;                    pCur=firstInOrder;                }                delete pCur;                pCur=NULL;            }        }        _pHead->_pLeft=LeftMost();        _pHead->_pRight=RightMost();        return true;    }    Node* LeftMost()    {        Node* pCur = GetRoot();        assert(pCur);        while(pCur->_pLeft)            pCur = pCur->_pLeft;        return pCur;    }    Node* RightMost()    {        Node* pCur = GetRoot();        assert(pCur);        while(pCur->_pRight)            pCur = pCur->_pRight;        return pCur;    }    Node*& GetRoot()const    {        return _pHead->_pParent;    }    Node* ToList()//转化为双向链表    {        //找链表头        Node* pHead=GetRoot();        if(NULL==pHead)            return;        while(pHead->_pLeft)            pHead=pHead->_pLeft;        Node* prev = NULL;        _ToList(GetRoot(), prev);        return pHead;    }protected:    void _InOrder(Node* pRoot)    {        if(pRoot)        {            _InOrder(pRoot->_pLeft);            cout<<pRoot->_key<<" ";            _InOrder(pRoot->_pRight);        }    }    void _ToList(Node* pRoot, Node*& prev)    {        if(pRoot)        {            _ToList(pRoot->_pLeft, prev);            // 当前节点的左指针域            pRoot->_pLeft = prev;            // 上一个结点的右指针域            if(prev)                prev->_pRight = pRoot;            prev = pRoot;            _ToList(pRoot->_pRight, prev);        }    }private:    Node* _pHead;};

测试代码:

#include"BSTIterator.hpp"void Test1(){    BSTree<int,int> bst;    int a[]={5,3,4,1,7,8,2,6,0,9};    for(int idx=0;idx<(sizeof(a)/sizeof(a[0]));++idx)    {        bst.Insert(a[idx],idx);    }    bst.InOrder();    bst.Find(8);    cout<<bst.GetMinKey()<<endl;    cout<<bst.GetMaxKey()<<endl;}void Test2()//情况三①②及情况一{    BSTree<int,int> bst;    int a[]={5,3,4,1,7,8,2,6,0,9};    //int a[]={5,3,4,1,8,2,6,7,0,9};    for(int idx=0;idx<(sizeof(a)/sizeof(a[0]));++idx)    {        bst.Insert(a[idx],idx);    }    bst.Remove(8);    bst.InOrder();    bst.Remove(6);    bst.InOrder();}void Test3()//情况三中的③{    BSTree<int,int> bst;    int a[]={5,7,8,6,9};    for(int idx=0;idx<(sizeof(a)/sizeof(a[0]));++idx)    {        bst.Insert(a[idx],idx);    }    bst.Remove(5);    bst.InOrder();}void Test4()//情况二{    BSTree<int,int> bst;    int a[]={5,3,4,1,7,6,0};    for(int idx=0;idx<(sizeof(a)/sizeof(a[0]));++idx)    {        bst.Insert(a[idx],idx);    }    bst.Remove(1);    bst.InOrder();    bst.Remove(7);    bst.InOrder();}void Test5()//情况四{    BSTree<int,int> bst;    int a[]={5,3,4,1,7,8,2,6,0,9};    for(int idx=0;idx<(sizeof(a)/sizeof(a[0]));++idx)    {        bst.Insert(a[idx],idx);    }    bst.Remove(5);    bst.InOrder();    bst.Remove(7);    bst.InOrder();}void Test6()//情况四{    BSTree<int,int> bst;    int a[]={5,3,4,1,7,8,2,0,9};    for(int idx=0;idx<(sizeof(a)/sizeof(a[0]));++idx)    {        bst.Insert(a[idx],idx);    }    bst.Remove(5);    bst.InOrder();}int main(){    Test1();    Test2();    Test3();    Test4();    Test5();    Test6();    return 0;}
原创粉丝点击