數據結構-二叉樹(應用篇)-之二叉搜索樹 C和C++的實現


一、概念

 

二叉搜索樹(Binary Sort Tree/Binary Search Tree...),是二叉樹的一種特殊擴展。也是一種動態查找表。

在二叉搜索樹中,左子樹上所有節點的均小於根節點,右子樹上所有節點的均值大於根節點

所以,如果使用中序遍歷的方法,樹數據剛好以從小到大的形式排好序並打印出來。

前驅:在二叉樹(前序/中序/后序)搜索中的上一個元素。

后繼:在二叉樹(前序/中序/后序)搜索中的下一個元素。

關於二叉樹的其它性質,可以看上一篇:http://www.cnblogs.com/HongYi-Liang/p/7231440.html




 

二、程序

C++:

在上一篇中,我們已經實現了二叉樹,本篇的二叉搜索樹將在上一遍的二叉樹類模板中繼承。

 

 BinarySearchTree.h

#ifndef _BINARYSEARCHTREE_H
#define _BINARYSEARCHTREE_H

#include <iostream>
#include <queue>
#include <vector>
#include "BinaryTree.h"
#include "BiTreeNode.h"


template <typename T>
class BinarySearchTree:public BinaryTree<T>
{
public:
    BinarySearchTree(int size,int rootIndex,T data);
    BinarySearchTree(vector<T> vect);
    virtual ~BinarySearchTree();

    //get
    vector<T> getResult();

    //add/delete
    bool addNode(int index,T data);
    bool insert(int index,T data, BiTreeNode<T> *pNode);
    bool deleteMinNode();
    bool deleteMaxNode();

    virtual bool deleteNodeByIndex(int index);                        //刪除節點(使用索引)
    virtual bool deleteNodeByNode(BiTreeNode<T> *pNode);            //刪除節點(使用地址)
    virtual bool deleteNodeByData(T data);                            //刪除節點(使用數據)

    //search
    bool searchNode(T data,BiTreeNode<T>** node);

    //sort
    bool sortToVec();
    bool sort(BiTreeNode<T> *pNode);

    //pinrtf
    void BSTreePreorderTraversal();                                        //先序遍歷
    void BSTreeInorderTraversal();                                        //中序遍歷
    void BSTreeSubsequentTraversal();                                    //后序遍歷

private:
    vector<T>  m_tVec;    
};

template <typename T>
BinarySearchTree<T>::BinarySearchTree(int size,int rootIndex,T data):BinaryTree(size,int rootIndex,T data)
{

}

template <typename T>
BinarySearchTree<T>::BinarySearchTree(vector<T> vect):BinaryTree((int)vect.size(),0,vect[0])
{
    unsigned int size = vect.size();
    for(unsigned int i=1;i<size;i++)
    {
        this->addNode(i,vect[i]);
    }
}

template <typename T>
BinarySearchTree<T>::~BinarySearchTree()
{
    
}

template <typename T>
vector<T> BinarySearchTree<T>::getResult()
{
    sortToVec();
    return m_tVec;
}

template <typename T>
bool BinarySearchTree<T>::addNode(int index,T data)
{
    if(IsTreeFull())
    {
        return false;
    }
    insert(index,data,m_pRoot);
    return true;
}

template <typename T>
bool BinarySearchTree<T>::insert(int index,T data, BiTreeNode<T> *pNode)
{
    if(data < pNode->getData())
    {
        if(pNode ->getLChild() != NULL)
        {
            if(insert(index,data,pNode->getLChild()))
                return true;
        }
        else
        {
            if(addLeftNodeByNode(index,data,pNode))
                return true;
        }
    }
    else
    {
        if(pNode ->getRChild() != NULL)
        {
            if(insert(index,data,pNode->getRChild()))
                return true;
        }
        else
        {
            if(addRightNodeByNode(index,data,pNode))
                return true;
        }        
    }
    return false;
}

template <typename T>
bool BinarySearchTree<T>::deleteMinNode()
{
    if(IsTreeEmpty())
        return false;

    BiTreeNode<T> *pNode = m_pRoot;
    while(pNode->getLChild() != NULL)
    {
        pNode = pNode->getLChild();
    }
    if(pNode==m_pRoot)
    {
        pNode = m_pRoot->getRChild();
        while(pNode->getLChild()!=NULL)
        {
            pNode = pNode->getLChild();
        }
    }

    deleteNodeByNode(pNode);
    return true ;
}

template <typename T>
bool BinarySearchTree<T>::deleteMaxNode()
{
    if(IsTreeEmpty())
        return false;

    BiTreeNode<T> *pNode = m_pRoot;
    while(pNode->getRChild() != NULL)
    {
        pNode = pNode->getRChild(); 
    }
    if(pNode==m_pRoot)
    {
        pNode = m_pRoot->getLChild();
        while(pNode->getRChild()!=NULL)
        {
            pNode = pNode->getRChild();
        }
    }

    deleteNodeByNode(pNode);
    return true;
}

template <typename T>
bool BinarySearchTree<T>::deleteNodeByIndex(int index)
{
    BiTreeNode<T> *pNode = getNodeByIndex(index);
    if(NULL != pNode)
    {
        /*there are 3 condition in the following:
            1、The node has no child.
            2、The node only has left child or right child.
            3、The node both has left and right child,so make the target node replaced by precursor,and then delete precursor by useing condition 2 function.
        */
        /*condition 1:no child*/
        if(NULL == pNode->getRChild() && NULL == pNode->getLChild())
        {
            if(pNode!=m_pRoot)
            {                
                BiTreeNode<T> *pfatherNode= pNode->getParent();
                if(pfatherNode->getLChild() == pNode)
                {
                    pfatherNode->setLChild(NULL);
                }
                else
                {
                    pfatherNode->setRChild(NULL);
                }
                this->m_iSize--;
                delete pNode;
            }
            else 
                return false;//only root left
        }
        /*condition 3:The node both has left and right child*/
        else if(NULL != pNode->getRChild() && NULL != pNode->getLChild())
        {
            BiTreeNode<T> *preNode = pNode->getInorderPrecursor();
            pNode->setIndex(preNode->getIndex());
            pNode->setData(preNode->getData());
            pNode = preNode;
        }
        /*condition 2: The node only has left child or right child.*/
        if(NULL == pNode->getRChild())
        {
            BiTreeNode<T> *pfatherNode= pNode->getParent();
            if(pfatherNode->getLChild() == pNode )//Target node is father left son.
            {
                pfatherNode->setLChild(pNode->getLChild());//Target node left son link to it fater.
            }
            else//Target node is father right son.
            {
                pfatherNode->setRChild( pNode->getLChild());//Target node left son link to it father.
            }
            pNode->setLChild(NULL);
            this->m_iSize--;
            delete pNode;
        }
        else if(NULL == pNode->getLChild())
        {
            BiTreeNode<T> *pfatherNode=pNode->getParent();
            if(pfatherNode->getLChild() == pNode )//Target node is father left son.
            {
                pfatherNode->setLChild(pNode->getRChild());//Target node left son link to it fater.
            }
            else//Target node is father right son.
            {
                pfatherNode->setRChild( pNode->getRChild());//Target node left son link to it father.
            }
            pNode->setRChild(NULL);
            this->m_iSize--;
            delete pNode;
        }
        return true;
    }
    else
        return false;//if(NULL != pNode); there are no such node!
}
template <typename T>
bool BinarySearchTree<T>::deleteNodeByNode(BiTreeNode<T> *pNode)
{
    return false;
}

template <typename T>
bool BinarySearchTree<T>::deleteNodeByData(T data)
{
    BiTreeNode<T> *pNode = m_pRoot;
    if(searchNode(data,&pNode))
    {
        /*there are 3 condition in the following:
            1、The node has no child.
            2、The node only has left child or right child.
            3、The node both has left and right child,so make the target node replaced by precursor,and then delete precursor by useing condition 2 function.
        */
        /*condition 1:no child*/
        if(NULL == pNode->getRChild() && NULL == pNode->getLChild())
        {
            if(pNode!=m_pRoot)
            {                
                BiTreeNode<T> *pfatherNode= pNode->getParent();
                if(pfatherNode->getLChild() == pNode)
                {
                    pfatherNode->setLChild(NULL);
                }
                else
                {
                    pfatherNode->setRChild(NULL);
                }
                this->m_iSize--;
                delete pNode;
            }
            else 
                return false;//only root left
        }
        /*condition 3:The node both has left and right child*/
        else if(NULL != pNode->getRChild() && NULL != pNode->getLChild())
        {
            BiTreeNode<T> *preNode = pNode->getInorderPrecursor();
            pNode->setIndex(preNode->getIndex());
            pNode->setData(preNode->getData());
            pNode = preNode;
        }
        /*condition 2: The node only has left child or right child.*/
        if(NULL == pNode->getRChild())
        {
            BiTreeNode<T> *pfatherNode= pNode->getParent();
            if(pfatherNode->getLChild() == pNode )//Target node is father left son.
            {
                pfatherNode->setLChild(pNode->getLChild());//Target node left son link to it fater.
            }
            else//Target node is father right son.
            {
                pfatherNode->setRChild( pNode->getLChild());//Target node left son link to it father.
            }
            pNode->setLChild(NULL);
            this->m_iSize--;
            delete pNode;
        }
        else if(NULL == pNode->getLChild())
        {
            BiTreeNode<T> *pfatherNode=pNode->getParent();
            if(pfatherNode->getLChild() == pNode )//Target node is father left son.
            {
                pfatherNode->setLChild(pNode->getRChild());//Target node left son link to it fater.
            }
            else//Target node is father right son.
            {
                pfatherNode->setRChild( pNode->getRChild());//Target node left son link to it father.
            }
            pNode->setRChild(NULL);
            this->m_iSize--;
            delete pNode;
        }
        return true;
    }
    else
        return false;//if(searchNode(data,&pNode)); there are no such node!
}


template <typename T>
bool BinarySearchTree<T>::searchNode(T data,BiTreeNode<T>** node)
{
    BiTreeNode<T> *pNode = m_pRoot;

    if(data>m_pRoot->getData())
    {
        while(data>pNode->getData())
        {
            if(pNode->getRChild() != NULL)
            {
                pNode = pNode->getRChild();
            }
            else
            {
                return false;
            }
        }
        while(data<pNode->getData())
        {
            if(pNode->getLChild() != NULL)
            {
                pNode = pNode->getLChild();
            }
            else
            {
                return false;
            }                
        }
        *node = pNode;
        return true;
    }
    else 
    {
        while(data<pNode->getData())
        {
            if(pNode->getLChild() != NULL)
            {
                pNode = pNode->getLChild();
            }
            else
            {
                return false;
            }                
        }    
        while(data>pNode->getData())
        {
            if(pNode->getRChild() != NULL)
            {
                pNode = pNode->getRChild();
            }
            else
            {
                return false;
            }
        }
        *node = pNode;
        return true;
    }
}

template <typename T>
bool BinarySearchTree<T>::sortToVec()
{
    m_tVec.clear();
    sort(m_pRoot);
    return true;
}

template <typename T> 
bool BinarySearchTree<T>::sort( BiTreeNode<T> *pNode)
{
    if(pNode->getLChild() != NULL)
    {
        sort(pNode->getLChild());
    }

    m_tVec.push_back(pNode->getData());

    if(pNode->getRChild() != NULL)
    {
        sort(pNode->getRChild());
    }

    return true;
}

template <typename T>
void BinarySearchTree<T>::BSTreePreorderTraversal()
{
    PreorderTraversal();
}

template <typename T>
void BinarySearchTree<T>::BSTreeInorderTraversal()
{
    InorderTraversal();
}

template <typename T>
void BinarySearchTree<T>::BSTreeSubsequentTraversal()
{
    SubsequentTraversal();
}

#endif 
View Code

BinaryTree.h

#ifndef _BINARYTREE_H
#define _BINARYTREE_H

#include <iostream>
#include <queue>
#include "BiTreeNode.h"
using namespace std;

template <typename T>
class BinaryTree
{
public:
    BinaryTree(int size,int index,T data);
    BinaryTree(int size);
    virtual ~BinaryTree();
    bool IsTreeEmpty();                                                //樹是否為空
    bool IsTreeFull();                                                //樹的容量是否已滿
    //search    
    BiTreeNode<T> *getNodeByIndex(int index);                        //通過索引搜索節點
    int getLeaves();                                                //獲取樹的葉子數
    int getHeight();                                                //獲取樹的高度(包含根節點)
    int getWidth();                                                    //獲取樹的寬度(包含根節點)
    int getNowSize();                                                //獲取樹現在的節點數(包含根節點)
    int getMaxSize();                                                //獲取樹的最大節點數
    //add/delete
    bool addLeftNodeByIndex(int newIndex,T data,int searchIndex);    //添加左子樹(使用索引)
    bool addRightNodeByIndex(int newIndex,T data,int searchIndex);  //添加右子樹(使用索引)
    bool addLeftNodeByNode(int index,T data,BiTreeNode<T> *pNode);  //添加左子樹(使用節點地址)
    bool addRightNodeByNode(int index,T data,BiTreeNode<T> *pNode); //添加右子樹(使用節點地址)

    virtual bool deleteNodeByIndex(int index);                        //刪除節點(使用索引)
    virtual bool deleteNodeByNode(BiTreeNode<T> *pNode);            //刪除節點(使用地址)

    //traversal
    void PreorderTraversal();                                        //先序遍歷
    void InorderTraversal();                                        //中序遍歷
    void SubsequentTraversal();                                        //后序遍歷

protected:
    BiTreeNode<T> *m_pRoot;                                            //tree root
    int m_iSize;                                                    //Tree now nodes size (without root)
    int m_iMaxSize;                                                    //Tree max nodes size (without root) 
};

template <typename T>
BinaryTree<T>::BinaryTree(int size,int index,T data)
{
    m_pRoot = new BiTreeNode<T>(index,data);
    m_pRoot->setLChild(NULL);
    m_pRoot->setRChild(NULL);
    m_pRoot->setParenet(NULL);
    m_iSize = 1;
    m_iMaxSize = size;    
}

template <typename T>
BinaryTree<T>::BinaryTree(int size)
{
    m_pRoot = new BiTreeNode<T>(0,0);
    m_pRoot->setLChild(NULL);
    m_pRoot->setRChild(NULL);
    m_pRoot->setParenet(NULL);
    m_iSize = 1;
    m_iMaxSize = size;
}


template <typename T>
BinaryTree<T>::~BinaryTree()
{
    if(NULL != m_pRoot)
        delete m_pRoot;
    m_pRoot=NULL;
}

template <typename T>
bool BinaryTree<T>::IsTreeEmpty()
{
    if(m_iSize == 0)
        return true;
    return false;    
}

template <typename T>
bool BinaryTree<T>::IsTreeFull()
{
    if(m_iSize >= m_iMaxSize)
        return true;
    return false;
}

//search
template <typename T>
BiTreeNode<T> *BinaryTree<T>::getNodeByIndex(int index)
{
    if(NULL == m_pRoot)
    {
        return NULL;
    }
    return m_pRoot->NodeSearch(index);
}

template <typename T>
int BinaryTree<T>::getLeaves()
{    
    if(NULL == m_pRoot)
    {
        return 0;
    }
    return m_pRoot->NodeLeavesStatistics();
}

template <typename T>
int BinaryTree<T>::getWidth()
{
    if(NULL == m_pRoot)
    {
        return 0;
    }
    int maxWidth=1;                //save max width
    int parentWidth=0;            //save this width
    int childrenWidth=0;        //save next width
    queue<BiTreeNode<T>*> stdQueue;
    BiTreeNode<T> *tempNode = m_pRoot;
    if(tempNode -> getLChild() != NULL)
    {
        stdQueue.push(tempNode -> getLChild());
        parentWidth ++;
    }
    if(tempNode -> getRChild() != NULL)
    {
        stdQueue.push(tempNode ->getRChild());
        parentWidth ++;
    }

    while(!stdQueue.empty())
    {
        while(parentWidth>0)
        {
            tempNode = stdQueue.front();
            stdQueue.pop();
            if(tempNode -> getLChild() != NULL)
            {
                stdQueue.push(tempNode -> getLChild());
                childrenWidth ++;
            }
            if(tempNode -> getRChild() != NULL)
            {
                stdQueue.push(tempNode ->getRChild());
                childrenWidth ++;
            }
            parentWidth --;
        }
        parentWidth = childrenWidth;
        if(parentWidth > maxWidth)
        {
            maxWidth = parentWidth;
        }
        childrenWidth =0;
    }

//    result =  m_pRoot->NodeChildrenNodeWidth(&child);
    return maxWidth;
}


template <typename T>
int BinaryTree<T>::getHeight()
{
    if(NULL == m_pRoot)
        return 0;
    return m_pRoot->NodeChildrenNodeHeigh();//including root 
}

template <typename T>
int BinaryTree<T>::getNowSize()
{
    if(NULL == m_pRoot)
    {
        return 0;
    }
    //return m_iSize;//quickly get Size
    return m_pRoot ->NodeChildrenStatistics();//including root
}

template <typename T>
int BinaryTree<T>::getMaxSize()
{
    return m_iMaxSize ;
}

//add/delete
template <typename T>
bool BinaryTree<T>::addLeftNodeByIndex(int newIndex,T data,int searchIndex)
{
    if(NULL == m_pRoot)
    {
        return false;
    }
    BiTreeNode<T> *tempNode;
    tempNode = m_pRoot->NodeSearch(searchIndex);//find the node that index  is = searchIndex
    if(tempNode!=NULL)
    {
        return addLeftNodeByNode(newIndex,data,tempNode);
    }
    return false;
}
template <typename T>
bool BinaryTree<T>::addRightNodeByIndex(int newIndex,T data,int searchIndex)
{
    if(NULL == m_pRoot)
    {
        return false;
    }
    BiTreeNode<T> *tempNode ;
    tempNode = m_pRoot->NodeSearch(searchIndex);
    if(tempNode!=NULL)
    {
        return addRightNodeByNode(newIndex,data,tempNode);
    }
    return false;
}
template <typename T>
bool BinaryTree<T>::addLeftNodeByNode(int index,T data,BiTreeNode<T> *pNode)
{
    BiTreeNode<T> *pNodeCopy = pNode;//make a copy of pNode to protect the pNode being changed by accidentally
    if(IsTreeFull())
    {
        return false ;
    }
    if(pNodeCopy -> getLChild() == NULL)
    {
        BiTreeNode<T> *newNode = new BiTreeNode<T>(index,data);
        pNodeCopy->setLChild(newNode);
        newNode->setParenet(pNodeCopy);
    }
    else 
    {
        return false ;
    }

    m_iSize++;
    return true;
}

template <typename T>
bool BinaryTree<T>::addRightNodeByNode(int index,T data,BiTreeNode<T> *pNode)
{
    BiTreeNode<T> *pNodeCopy = pNode;//make a copy of pNode to protect the pNode being changed by accidentally
    if(IsTreeFull())
    {
        return false ;
    }
    if(pNodeCopy -> getRChild() == NULL)
    {
        BiTreeNode<T> *newNode = new BiTreeNode<T>(index,data);
        pNodeCopy->setRChild(newNode);
        newNode->setParenet(pNodeCopy);
    }
    else 
    {
        return false ;
    }

    m_iSize++;
    return true;
}


template <typename T>
bool BinaryTree<T>::deleteNodeByIndex(int index)
{
    if(IsTreeEmpty())
    {
        return false;
    }

    BiTreeNode<T> *deleteNode = m_pRoot->NodeSearch(index);
    if(deleteNode != NULL)
    {
        if(deleteNode == m_pRoot)
        {
            cout<<"BinaryTree<T>::deleteNodeByIndex():"<<index<<"是根節點不能刪除"<<endl;
            return false;
        }
        return deleteNodeByNode(deleteNode);
    }
    return false;
}
template <typename T>
bool BinaryTree<T>::deleteNodeByNode(BiTreeNode<T> *pNode)
{
    if(IsTreeEmpty())
        return false;

    if(pNode!=NULL)
    {
        /*clear parent Node L/RChild*/ 
        BiTreeNode<T> *parentNode = pNode->getParent();
        if(parentNode != NULL)
        {
            if(parentNode->getLChild() == pNode)
            {
                parentNode->setLChild(NULL);
            }
            else
            {
                parentNode->setRChild(NULL);
            }
        }
        /*delete node*/
        int SizeDec;//use to caculate how much Node was delete
        SizeDec = pNode->NodeDelete();
        m_iSize-=SizeDec;
        return true;
    }
    return false;
}

//traversal
template <typename T>
void BinaryTree<T>::PreorderTraversal()
{
    cout<<"PerorderTraversal:"<<endl;
    if(NULL == m_pRoot)
    {
        return ;
    }
    m_pRoot ->NodePreorderTraversal();
}
template <typename T>
void BinaryTree<T>::InorderTraversal()
{
    cout<<"InorderTraversal:"<<endl;
    if(NULL == m_pRoot)
    {
        return ;
    }
    m_pRoot ->NodeInorderTraversal();
}
template <typename T>
void BinaryTree<T>::SubsequentTraversal()
{
    cout<<"SubsequentTraversal:"<<endl;
    if(NULL == m_pRoot)
    {
        return ;
    }
    m_pRoot ->NodeSubsequentTraversal();
}

#endif 
View Code

BiTreeNode.h

#ifndef _BITREENODE_H
#define _BITREENODE_H
#include<iostream>
using namespace std;


template <typename T>
class BiTreeNode
{
public:
    BiTreeNode();
    BiTreeNode(int index,T data);
    virtual ~BiTreeNode();
    //get data
    int getIndex();
    T getData();
    BiTreeNode *getParent();
    BiTreeNode *getLChild();
    BiTreeNode *getRChild();
    BiTreeNode *getInorderPrecursor();                    //獲取中序前驅
    BiTreeNode *getInorderSubsequence();                //獲取中序后繼
    //set data
    void setIndex(int index);
    void setData(T data);
    void setParenet(BiTreeNode *Node);
    void setLChild(BiTreeNode *Node);
    void setRChild(BiTreeNode *Node);
    //else
    BiTreeNode *NodeSearch(int index);                    //通過索引搜索節點(以本節點作為根尋找樹的某個節點)
    int NodeLeavesStatistics(int leaves = 0);            //統計葉子數
    int NodeChildrenNodeHeigh();                        //統計子節點的最大高度(包含本節點)/(以本節點作為根求樹的高度)
    int NodeChildrenStatistics();                        //統計子節點數(包含本節點)
    int NodeDelete();                                    //刪除節點
    //traversal
    void NodePreorderTraversal();
    void NodeInorderTraversal();
    void NodeSubsequentTraversal();

private:
    int m_iIndex;
    T m_tData;
    BiTreeNode *m_pParent;
    BiTreeNode *m_pLeftChild;
    BiTreeNode *m_pRightChild;

    //struct NodeWidth<T> stNodeWidth;
};

template <typename T>
BiTreeNode<T>::BiTreeNode()
{
    m_iIndex = 0;
    m_tData = 0;
    m_pParent = NULL;
    m_pLeftChild = NULL;
    m_pRightChild = NULL;
}

template <typename T>
BiTreeNode<T>::BiTreeNode(int index,T data)
{
    m_iIndex = index;
    m_tData = data;
    m_pParent = NULL;
    m_pLeftChild = NULL;
    m_pRightChild = NULL;
}

template <typename T>
BiTreeNode<T>::~BiTreeNode()
{
    if(m_pLeftChild != NULL)
    {
        m_pLeftChild->NodeDelete();
        m_pLeftChild = NULL;
    }
    if(m_pRightChild != NULL)
    {
        m_pRightChild->NodeDelete();
        m_pRightChild = NULL;
    }
    m_pParent = NULL;
}
/*-----------------------getdata------------------------*/
template <typename T>
int BiTreeNode<T>::getIndex()
{
    return m_iIndex;
}


template <typename T>
T BiTreeNode<T>::getData()
{
    return m_tData;
}

template <typename T>
BiTreeNode<T> *BiTreeNode<T>::getParent()
{
    return m_pParent;
}

template <typename T>
BiTreeNode<T> *BiTreeNode<T>::getLChild()
{
    return m_pLeftChild;
}

template <typename T>
BiTreeNode<T> *BiTreeNode<T>::getRChild()
{
    return m_pRightChild;
}

template <typename T>
BiTreeNode<T> *BiTreeNode<T>::getInorderPrecursor()
{
    /*
        condition 1: Node has left child.
        condition 2: Node hasn't left child,and it is its father right child.
        condition 3: Node hasn't left child,and it is its father left child.
    */
    /*condition 1:node has left child*/
    if(NULL != this->getLChild())
    {
        BiTreeNode *tempNode=this->getLChild();
        while(NULL != tempNode->getRChild() )
        {
            tempNode=tempNode->getRChild();
        }
        return  tempNode;
    }
    else
    {
        BiTreeNode *fatherNode=this->getParent();
        if(NULL == fatherNode)
        {
            return NULL;//it is root.
        }
        /*condition 2*/
        else if(fatherNode->getRChild() == this)
        {
            return fatherNode;
        }
        /*condition*/
        else
        {
            while( fatherNode->getParent()->getRChild() != fatherNode)
            {
                fatherNode =fatherNode ->getParent();
                if(NULL == fatherNode )
                {
                    return NULL;//it is root;
                }
            }
            return fatherNode->getParent();
        }
    }
    return NULL;
}

template <typename T>
BiTreeNode<T> *BiTreeNode<T>::getInorderSubsequence()                //獲取中序后繼
{
    /*
        condition 1: Node has right child.
        condition 2: Node hasn't right child,and it is its father left child.
        condition 3: Node hasn't right child,and it is its father right child.
    */    
    /*condition 1*/
    if(NULL != this->getRChild())
    {
        BiTreeNode *tempNode = this->getRChild();
        while(NULL != tempNode->getLChild() )
        {
            tempNode=tempNode->getLChild();
        }
        return  tempNode;
    }
    /*condition 2*/
    else
    {
        BiTreeNode *fatherNode=this->getParent();
        if(NULL == fatherNode)//it is root.
        {
            return NULL;
        }
        else if(fatherNode->getLChild() == this)
        {
            return fatherNode;
        }
        else
        {
            while(fatherNode->getParent()->getLChild() !=fatherNode)
            {
                fatherNode=fatherNode->getParent();
                if(NULL == fatherNode)
                {
                    return NULL;//it is root;
                }
            }
            return fatherNode->getParent();
        }
    }
}
/*-----------------------setdata------------------------*/
template <typename T>
void BiTreeNode<T>::setIndex(int index)
{
    m_iIndex = index;
}
template <typename T>
void BiTreeNode<T>::setData(T data)
{
    m_tData = data;
}
template <typename T>
void BiTreeNode<T>::setParenet(BiTreeNode *Node)
{
    m_pParent = Node;
}

template <typename T>
void BiTreeNode<T>::setLChild(BiTreeNode *Node)
{
    m_pLeftChild = Node;
}

template <typename T>
void BiTreeNode<T>::setRChild(BiTreeNode *Node)
{
    m_pRightChild = Node;
}

/*-----------------------else------------------------*/
template <typename T>
BiTreeNode<T> *BiTreeNode<T>::NodeSearch(int index)
{
    BiTreeNode<T> *tempNode = NULL;
    if(m_iIndex == index)
    {
        return this;
    }
    if(m_pLeftChild != NULL)
    {
        tempNode = m_pLeftChild->NodeSearch(index);
        if(tempNode != NULL)//match
        {
            return tempNode;
        }
    }

    if(m_pRightChild !=NULL)
    {
        tempNode = m_pRightChild->NodeSearch(index);
        if(tempNode != NULL)// match
        {
            return tempNode;
        }
    }


    return NULL;
}

/*statistcal children node heigh(includding me)*/
template <typename T>
int BiTreeNode<T>::NodeChildrenNodeHeigh()
{
    int heightLeft =0 ;
    int heightRight =0; 
    if(m_pLeftChild != NULL)
    {
        heightLeft += m_pLeftChild->NodeChildrenNodeHeigh();    
    }
    if(m_pRightChild != NULL)
    {
        heightRight += m_pRightChild->NodeChildrenNodeHeigh();
    }
    if(heightRight > heightLeft)
    {
        return ++heightRight;
    }
    else
    {
        return ++heightLeft;
    }
}

/*statistcal leaves node(includding me)*/
template <typename T>
int BiTreeNode<T>::NodeLeavesStatistics(int leaves)
{
    if(this->m_pLeftChild != NULL)
    {
        leaves = this->m_pLeftChild->NodeLeavesStatistics(leaves);
    }
    if(this->m_pRightChild != NULL)
    {
        leaves = this->m_pRightChild->NodeLeavesStatistics(leaves);
    }
    if(this->getLChild() == NULL && this->getRChild() == NULL)
    {
        leaves ++;
    }
    return leaves;    
}
/*statistcal children node(includding me)*/
template <typename T>
int BiTreeNode<T>::NodeChildrenStatistics()
{
    int iCnt=0;
    if(this->m_pLeftChild != NULL)
    {
        iCnt+=this->m_pLeftChild->NodeChildrenStatistics();
    }
    if(this->m_pRightChild!= NULL)
    {
        iCnt+=this->m_pRightChild->NodeChildrenStatistics();
    }
    iCnt++;
    return iCnt;
}

template <typename T>
int  BiTreeNode<T>::NodeDelete()
{
    int Times=0;
    if(this->m_pLeftChild != NULL)
    {
         //delete this->getLChild();
        Times+=this->m_pLeftChild->NodeDelete();
        this->m_pLeftChild =NULL;
    }
    if(this->m_pRightChild!= NULL)
    {
        //delete this->getRChild();
        Times+=this->m_pRightChild->NodeDelete();
        this->m_pRightChild =NULL;
    }
    Times++;
    delete this;
    return Times;
}
/*-----------------------traversal------------------------*/
template <typename T>
void BiTreeNode<T>::NodePreorderTraversal()
{
    cout<<"Index:"<<this->getIndex()<<";Data:"<<this->getData()<<endl;

    if(this->getLChild() != NULL)
    {
        this->getLChild()->NodePreorderTraversal();
    }

    if(this->getRChild() != NULL)
    {
        this->getRChild()->NodePreorderTraversal();
    }
}

template <typename T>
void BiTreeNode<T>::NodeInorderTraversal()
{
    if(this->getLChild() != NULL)
    {
        this->getLChild()->NodeInorderTraversal();
    }

    cout<<"Index:"<<this->getIndex()<<";Data:"<<this->getData()<<endl;

    if(this->getRChild() != NULL)
    {
        this->getRChild()->NodeInorderTraversal();
    }
}

template <typename T>
void BiTreeNode<T>::NodeSubsequentTraversal()
{
    if(this->getLChild() != NULL)
    {
        this->getLChild()->NodeSubsequentTraversal();
    }

    if(this->getRChild() != NULL)
    {
        this->getRChild()->NodeSubsequentTraversal();
    }

    cout<<"Index:"<<this->getIndex()<<";Data:"<<this->getData()<<endl;
}

#endif
View Code

 main.c

#include <iostream>
#include <vector>
#include "BinaryTree.h"
#include "BinarySearchTree.h"

using namespace std;


int main()
{
    /*初始化一個vec向量用於建樹*/
    vector<int> Vec1;
    Vec1.push_back(41);
    Vec1.push_back(20);
    Vec1.push_back(65);
    Vec1.push_back(11);
    Vec1.push_back(29);
    Vec1.push_back(50);
    Vec1.push_back(91);
    Vec1.push_back(32);
    Vec1.push_back(72);
    Vec1.push_back(99);
    /*建立一顆搜索二叉樹*/
    BinarySearchTree<int> BSTree(Vec1); 
    /*中序遍歷*/
    BSTree.BSTreeInorderTraversal();
    /*排序並按順序打印*/
    vector<int> Vec2 = BSTree.getResult();
    for(unsigned int i=0;i<Vec2.size();i++)
    {
        cout<<Vec2[i]<<" ";
    }
    cout<<endl;
    /*獲取元素個數*/
    cout<<"size:"<<BSTree.getNowSize()<<endl;
    cout<<"width:"<<BSTree.getWidth()<<endl;
    cout<<"height:"<<BSTree.getHeight()<<endl;

    /*刪除元素*/
//    BSTree.deleteMinNode();
//    BSTree.deleteMaxNode();
    BSTree.deleteNodeByData(50);
    //BSTree.deleteNodeByIndex(50);
    Vec2 = BSTree.getResult();
    for(unsigned int i=0;i<Vec2.size();i++)
    {
        cout<<Vec2[i]<<" ";
    }
    cout<<endl;
    cout<<"size:"<<BSTree.getNowSize()<<endl;

    system("pause");
    return 0;
}

 

 構建二叉樹如圖所示

運行結果:

 

 

 

在程序中,主要講述以下兩個重點:

  1. 添加節點
  2. 刪除節點

添加節點:

 

先看下,對於二叉搜索樹,

 

刪除節點:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM