溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

向原文學(xué)習(xí)   已添加字母說明 BST 排序二叉樹

發(fā)布時間:2020-06-25 12:27:32 來源:網(wǎng)絡(luò) 閱讀:325 作者:wzdouban 欄目:編程語言
  
  /***************************
   運(yùn)行環(huán)境  http://www.anycodes.cn/zh/
   原文件  http://www.cnblogs.com/hanxi/archive/2012/08/18/2645929.html
   帶注釋的C++類版本 BST 二叉搜索樹
   ***************************/
  
#ifndef BTREE_H_
#define BTREE_H_
 
#include <cstdlib>
#include <iostream>
 #include <iomanip> 
using namespace std;

template <class TreeDataType>
class BSTree
{
private:
    class BSTNode
    {
    public:
        BSTNode* left;
        BSTNode* right;
        TreeDataType data; BSTNode():left(NULL),right(NULL) {}
        BSTNode(TreeDataType a_data):data(a_data),left(NULL),right(NULL) {}
    };//節(jié)點(diǎn)聲明
    typedef BSTNode* BSTNodePointer;
    BSTNodePointer m_root;

public:
    BSTree():m_root(NULL) {}
    ~BSTree() {deleteNode(m_root);}
    bool isEmpty() const {return m_root == NULL;}
    bool find(const TreeDataType& a_data) const;
    void insert(const TreeDataType& a_data) {insertAux(m_root,a_data);}
    void remove(const TreeDataType& a_data);
    void inorder(ostream& out) const {inorderAux(out, m_root);}
    void graph(ostream& out) const {graphAux(out, 0, m_root);}

protected:
    void deleteNode(BSTNodePointer a_node);/*/刪除節(jié)點(diǎn)和所有到子節(jié)點(diǎn)/*/
    void insertAux(BSTNodePointer& a_subRoot, const TreeDataType& a_data);
    void inorderAux(ostream& out, BSTNodePointer a_subRoot) const;
    void graphAux(ostream& out, int a_indent, BSTNodePointer a_subRoot) const;
    void find2(const TreeDataType& a_data, bool& found, BSTNodePointer& a_locPtr, BSTNodePointer& a_parent) const; 
};/*/類模板聲明結(jié)束/*/
#endif

template <class TreeDataType>
inline void BSTree<TreeDataType>::deleteNode(BSTree<TreeDataType>::BSTNodePointer a_node)
{/*/遞歸刪除結(jié)點(diǎn)/*/
    if (a_node->left != NULL)
    {
        deleteNode(a_node->left);
    }
    else if (a_node->right != NULL)
    {
        deleteNode(a_node->right);
    }
    else if (a_node != NULL)
    {
        delete a_node;
        a_node = NULL;
    }
}

template <class TreeDataType>
inline void BSTree<TreeDataType>::insertAux(BSTree<TreeDataType>::BSTNodePointer& a_subRoot, const TreeDataType& a_data)
{/*/ 遞歸 插入結(jié)點(diǎn) /*/
    if (a_subRoot == NULL)
    {
        a_subRoot = new BSTree<TreeDataType>::BSTNode(a_data);
    }
    else if (a_data < a_subRoot->data)
    {
        insertAux(a_subRoot->left,a_data);
    }
    else if (a_subRoot->data < a_data)
    {
        insertAux(a_subRoot->right,a_data);
    }
    else
    {/*/不能有相同的結(jié)點(diǎn)/*/
        std::cerr << "a_data already in the tree!\n";
    }
}

template <class TreeDataType>
inline void BSTree<TreeDataType>::inorderAux(ostream& out, BSTree<TreeDataType>::BSTNodePointer a_subRoot) const
{/*/LDR中序遍歷/*/
    if (a_subRoot != NULL)
    {
        inorderAux(out, a_subRoot->left);//L
        out << a_subRoot->data << " ";//V
        inorderAux(out, a_subRoot->right);//R
    }
}


template <class TreeDataType>
inline void BSTree<TreeDataType>::graphAux(ostream& out, int a_indent, BSTree<TreeDataType>::BSTNodePointer a_subRoot) const
{/*/圖表式打印樹/*/
    if (a_subRoot != NULL)
    {
        graphAux(out, a_indent+8, a_subRoot->right);                //R
        out << setw(a_indent) << " " << a_subRoot->data << endl;    //V
        graphAux(out, a_indent+8, a_subRoot->left);                    //L
    }
}

template <class TreeDataType>
inline bool BSTree<TreeDataType>::find(const TreeDataType& a_data) const
{
    BSTree<TreeDataType>::BSTNodePointer locPtr = m_root;
    bool found = false;
    while (!found && locPtr != NULL)
    {
        if (a_data < locPtr->data)
        {
            locPtr = locPtr->left;
        }
        else if (locPtr->data < a_data)
        {
            locPtr = locPtr->right;
        }
        else
        {
            found = true;
        }
    }
    return found;
}

template <class TreeDataType>
inline void BSTree<TreeDataType>::find2(const TreeDataType& a_data, bool& found, 
                                BSTree<TreeDataType>::BSTNodePointer& a_locPtr,
                                BSTree<TreeDataType>::BSTNodePointer& a_parent) const
{/*/ 這里不僅要找 還要找到p結(jié)點(diǎn) 已便于后期 刪除找到的結(jié)點(diǎn) /*/
    a_locPtr = m_root;
    a_parent = NULL;
    found = false;
    while (!found && a_locPtr != NULL)
    {
        if (a_data < a_locPtr->data)
        {
            a_parent = a_locPtr; 
            a_locPtr = a_locPtr->left;
        }
        else if (a_locPtr->data < a_data)
        {
            a_parent = a_locPtr; 
            a_locPtr = a_locPtr->right;
        }
        else
        {
            found = true;
        }
    }
}

template <class TreeDataType>
inline void BSTree<TreeDataType>::remove(const TreeDataType& a_data)
{
    bool found = false;
    BSTree<TreeDataType>::BSTNodePointer x; //被刪除的節(jié)點(diǎn)
    BSTree<TreeDataType>::BSTNodePointer parent;
    find2(a_data,found,x,parent);
    if (!found)
    {
        std::cerr << "a_data is not in the tree!\n";
        return;
    }
    
    if (x->left != NULL && x->right != NULL)//節(jié)點(diǎn)有兩個子女
    {
        //查找x的中續(xù)后繼節(jié)點(diǎn)及其雙親節(jié)點(diǎn)
        BSTree<TreeDataType>::BSTNodePointer xSucc = x->right;
        parent = x;
        while (xSucc->left != NULL)/*/ 在右中找最左的元素/*/
        {
            parent = xSucc;
            xSucc = xSucc->left;
        }
        x->data = xSucc->data; /*/  替換要刪除的結(jié)點(diǎn)數(shù)據(jù)/*/
        x = xSucc;             /*/    轉(zhuǎn)向這個替死鬼/*/
    }
    BSTree<TreeDataType>::BSTNodePointer subTree = x->left;
    if (subTree == NULL)       /*/    看替死鬼的情況  /*/
    {                           
        subTree = x->right;     
    }
    if (parent == NULL)
    {
        m_root = subTree;
    }
    else if (parent->left == x)
    {
        parent->left = subTree;         /*/替死鬼的右做p的左 /*/
    }
    else
    {
        parent->right = subTree;        /*/替死鬼是p的右孩子,將右孩子做p的右孩子 /*/
    }
    delete x;
}
 /*/  
 -----------文件分割線-------"BSTree.h"----------------
#include "BSTree.h"
#include <cstdlib>
#include <iostream>
using namespace std;
/*/ 
int test()
{
/*/ 
數(shù)據(jù)準(zhǔn)備 int a[]
/*/	
int a[]={1,3,5,7,9,2,4,6,8,-999};
int  i=0;
    BSTree<int> intBST;
    cout << "Constructing empty BST\n";
    cout << "BST " << (intBST.isEmpty()?"is":"is not") << "empty\n";

    int number;
    for (;;)
    {   number=a[i++];
        if (number == -999) break;
        intBST.insert(number);
    }
    intBST.inorder(cout);
    cout << endl;
    intBST.graph(cout);
    
    //測試find
    for (i=0;;i++)
    {
        cout << "Item to find (-999 to stop):";
         number=a[i];
        if (number == -999) break;
        bool found = intBST.find(number);
        cout << boolalpha << found << endl;
    }
    
    //測試remove
      for (i=0;;i++)
    {
        cout << "Item to remove (-999 to stop):"<<endl; 
             number=a[i];
        if (number == -999) break;
        intBST.remove(a[i]);
        intBST.graph(cout);
        cout << endl;
    }
    intBST.inorder(cout);     
}
void use()
{
 
    BSTree<int> intBST;
    cout << "Constructing empty BST\n";
    cout << "BST " << (intBST.isEmpty()?"is":"is not") << "empty\n";
    int number;
    for (;;)
    {
        cout << "Item to insert (-999 to stop):"<<endl;
        cin >> number;
        if (number == -999) break;
        intBST.insert(number);
    }
    intBST.inorder(cout);
    cout << endl;
    intBST.graph(cout);
    
    //測試find
    for (;;)
    {
        cout << "Item to find (-999 to stop):";
        cin >> number;
        if (number == -999) break;
        bool found = intBST.find(number);
        cout << boolalpha << found << endl;
    }
    
    //測試remove
    for (;;)
    {
        cout << "Item to remove (-999 to stop):";
        cin >> number;
        if (number == -999) break;
        intBST.remove(number);
        cout << endl;
        intBST.graph(cout);
        cout << endl;
    }
    intBST.inorder(cout);    
}
int main()
{
    test(); return 0;
}


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI