二叉搜索树---递归及非递归

来源:互联网 发布:佳能格式转换软件 编辑:程序博客网 时间:2024/06/08 12:21

二叉搜索树又称为二叉排序树,它为一棵空树,或者是一棵左子树所有节点的值比根节点小,右子树所有节点的值比根节点大的一棵树。

性质:
①.二叉搜索树中,最左边的结点值最小,最右边的结点值最大
②中序遍历一棵二叉搜索树,所有节点的值是按顺序排列的

   构造一棵二叉搜索树时,比较插入结点的key值,key小于根节点的_key时,向根节点的左边走,大于根节点的_key值时,向根节点的右边走;   删除二叉搜索树中的某个结点时,分为四种情况;

删除二叉搜索树中某个节点的情况及处理方法如下:

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

二叉搜索树的基本操作代码如下:

BSTree.hpp

#pragma once#include<iostream>using namespace std;#include<assert.h>template<class k,class v>struct BSNode{    BSNode(const k& key,const v& value)        :_pLeft(NULL)        ,_pRight(NULL)        ,_key(key)        ,_value(value)    {}    BSNode<k,v>* _pLeft;    BSNode<k,v>* _pRight;    k _key;    v _value;};template<class k,class v>class BSTree{    typedef BSNode<k,v> Node;public:    BSTree()        :_pRoot(NULL)    {}    ~BSTree()    {        _DestroyBSTree(_pRoot);    }    BSTree<k,v>& operator=(const BSTree<k,v>& bst)    {        if(this!=&bst)        {            _DestroyBSTree(_pRoot);            _pRoot=_CopyBSTree(bst._pRoot);        }        return *this;    }    Node* Find(const k& key)//查找某个节点--非递归    {        Node* pCur=_pRoot;        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)//插入某个节点--非递归    {        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;            }            else//等于根节点,不需要插入            {                return false;            }        }        //插入到叶子结点后时        pCur=new Node(key,value);        if(key<pParent->_key)            pParent->_pLeft=pCur;        else            pParent->_pRight=pCur;        return true;    }    void InOrder()//中序遍历    {        cout<<"InOrder:"<<endl;        _InOrder(_pRoot);        cout<<endl;    }    const k& GetMaxKey()const//找最右结点(最大)    {        assert(_pRoot);        Node* pCur=_pRoot;        while(pCur->_pRight)            pCur=pCur->_pRight;        return pCur->_key;    }    const k& GetMinKey()const//找最左结点(最小)    {        assert(_pRoot);        Node* pCur=_pRoot;        while(pCur->_pLeft)            pCur=pCur->_pLeft;        return pCur->_key;    }    bool Remove(const k& key)//删除key结点--非递归    {        //树为空,不能删除结点        if(NULL==_pRoot)            return false;        //只有一个根节点,要删除的结点正好是根节点        if(NULL==_pRoot->_pLeft && NULL==_pRoot->_pRight && key==_pRoot->_key)        {                                                                                 delete _pRoot;            _pRoot=NULL;            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;            }                   else                break;//找到了该节点        }        //已找到待删除结点---》1.没有左孩子,只有右孩子                             //2.没有右孩子,只有左孩子                            // 3.左右孩子都没有                             //4.左右孩子都存在                             //可以合并1,3 或2,3        if(pCur)        {   //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;            return true;        }        return false;    }//递归版本    //Node* Find(const k& key)//递归找结点    //{    //  Node* pCur=NULL;    //  pCur=_Find(_pRoot,key);    //  cout<<pCur->_key<<endl; //       return pCur;    //} //   bool Insert(const k& key,const v& value)//递归插入    //{ //       return _Insert(_pRoot,key,value);    //}    //bool Remove(const k& key)//递归删除    //{ //       return _Remove(_pRoot,key);    //}protected:    Node* _CopyBSTree(Node* pRoot)//拷贝    {        Node* pNewRoot=NULL;        if(pRoot)        {            //拷贝根节点            pNewRoot=new Node(pRoot->_value);            //拷贝左子树            pNewRoot->_pLeft=_CopyBSTree(pRoot->_pLeft);            //拷贝右子树            pNewRoot->_pRight=_CopyBSTree(pRoot->_pRight);        }        return pNewRoot;    }    void _DestroyBSTree(Node* &pRoot)    {        if(pRoot)        {            _DestroyBSTree(pRoot->_pLeft);            _DestroyBSTree(pRoot->_pRight);            delete pRoot;            pRoot=NULL;        }    }    void _InOrder(Node* pRoot)    {        if(pRoot)        {            _InOrder(pRoot->_pLeft);            cout<<pRoot->_key<<" ";            _InOrder(pRoot->_pRight);        }    } //   Node* _Find(Node* pRoot,const k& key)//递归找    //{    //  if(NULL==pRoot)    //      return NULL;    //  if(key==pRoot->_key)    //      return pRoot;    //  else if(key<pRoot->_key)    //      return _Find(pRoot->_pLeft,key);    //  else    //      return _Find(pRoot->_pRight,key);    //}    //bool _Insert(Node*& pRoot,const k& key,const v& value)//递归插入    //{    //  if(NULL==pRoot)    //  {    //      pRoot=new Node(key,value);    //      return true;    //  }    //  if(key<pRoot->_key)    //      return _Insert(pRoot->_pLeft,key,value);    //  else if(key>pRoot->_key)    //      return _Insert(pRoot->_pRight,key,value);    //  else     //      return false;    //}    //bool _Remove(Node*& pRoot,const k& key)//递归删除    //{    //  if(NULL==pRoot)    //      return false;    //  else    //  {    //      if(key<pRoot->_key)    //          _Remove(pRoot->_pLeft,key);    //      else if(key>pRoot->_key)    //          _Remove(pRoot->_pRight,key);    //      else    //      {    //          Node* pDel=pRoot;    //          if(NULL==pRoot->_pLeft)    //          {    //              pRoot=pRoot->_pRight;    //              delete pDel;    //              return true;    //          }    //          else if(NULL==pRoot->_pRight)    //          {    //              pRoot=pRoot->_pLeft;    //              delete pDel;    //              return true;    //          }    //          else    //          {    //              Node* firstInOrder=pRoot->_pRight;    //              while(firstInOrder->_pLeft)//找要删除结点的右子树中最小结点进行交换    //                  firstInOrder=firstInOrder->_pLeft;    //              pDel->_key=firstInOrder->_key;    //              //              return _Remove(pRoot->_pRight,firstInOrder->_key);    //          }    //      }    //  }    //  return false;    //}private:    Node* _pRoot;};

测试代码:
BST.cpp

#include"BSTree.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;}
原创粉丝点击