向原文学习   已添加字母说明 BST 排序二叉树

发布时间:2020-06-25 12:27:32 作者:wzdouban
来源:网络 阅读:329
  
  /***************************
   运行环境  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) {}
    };//节点声明
    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);/*/删除节点和所有到子节点/*/
    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; 
};/*/类模板声明结束/*/
#endif

template <class TreeDataType>
inline void BSTree<TreeDataType>::deleteNode(BSTree<TreeDataType>::BSTNodePointer a_node)
{/*/递归删除结点/*/
    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)
{/*/ 递归 插入结点 /*/
    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
    {/*/不能有相同的结点/*/
        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结点 已便于后期 删除找到的结点 /*/
    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; //被删除的节点
    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)//节点有两个子女
    {
        //查找x的中续后继节点及其双亲节点
        BSTree<TreeDataType>::BSTNodePointer xSucc = x->right;
        parent = x;
        while (xSucc->left != NULL)/*/ 在右中找最左的元素/*/
        {
            parent = xSucc;
            xSucc = xSucc->left;
        }
        x->data = xSucc->data; /*/  替换要删除的结点数据/*/
        x = xSucc;             /*/    转向这个替死鬼/*/
    }
    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()
{
/*/ 
数据准备 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;
}


推荐阅读:
  1. 线程方面的程序注意点
  2. 力软敏捷开发框架帮您开发什么软件

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

小代码 bs

上一篇:粗略模仿google+圈子拖拽效果   -----   JQUERY特效模板

下一篇:OGG运维优化脚本(五)-信息修改类--批量注释

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》