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

  
  /***************************
   运行环境  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;
}
时间: 2024-10-14 04:31:52

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

iOS: 学习笔记, 添加一个带界面约束的控制器

1. 创建一个空iOS应用程序(Empty Application). 2. 添加加控制器类. 修改控制器类的viewDidLoad 1 - (void)viewDidLoad 2 { 3 [super viewDidLoad]; 4 //创建标题 5 UILabel *header = [[UILabel alloc] init]; 6 header.text = @"欢迎来到我的世界!"; 7 header.textAlignment = NSTextAlignmentCenter

System.ArgumentException: 已添加项。字典中的关键字:XX 所添加的关键字:XX

    异常详细信息: System.ArgumentException: 已添加项.字典中的关键字:"sftj_dt"所添加的关键字:"sftj_dt" 这是在给Hashtable添加值的时候报的错 是在Hashtable中Key有重复值了,可以用 table.Remove(tableID); 先把值排除再添加就可以了

mvc已添加了具有相同键的项

异常详细信息: System.ArgumentException: 已添加了具有相同键的项. 场景重现:在地址栏输入  http://localhost:51709/Home/Index?user[0].Name=tom&user[1].Name=jack 后台代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namesp

C# 后台服务 web.config 中 项“ConnectionString”已添加。问题

是自己在一网站下建了虚拟目录.原本网站为空,后来自己改了路径,有了默认配置很久后打开原本ok的虚拟目录,坑爹了.杯具了.代码:ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString 出错:<?xml version="1.0" encoding="utf-8" ?>   <string xmlns="http://tempu

深度学习在美团点评推荐平台排序中的应用--学习笔记

写在前面:据说下周就要xxxxxxxx, 吓得本宝宝赶紧找些广告的东西看看 gbdt+lr的模型之前是知道怎么搞的,dnn+lr的模型也是知道的,但是都没有试验过 深度学习在美团点评推荐平台排序中的运用 原创 2017-07-28 潘晖 美团点评技术团队 美团点评作为国内最大的生活服务平台,业务种类涉及食.住.行.玩.乐等领域,致力于让大家吃得更好,活得更好,有数亿用户以及丰富的用户行为.随着业务的飞速发展,美团点评的用户和商户数在快速增长.在这样的背景下,通过对推荐算法的优化,可以更好的给用户

深度学习在美团点评推荐平台排序中的运用

深度学习在美团点评推荐平台排序中的运用 原文地址:https://tech.meituan.com/dl.html 潘晖 美团点评搜索推荐团队 ·2017-07-28 14:33 美团点评作为国内最大的生活服务平台,业务种类涉及食.住.行.玩.乐等领域,致力于让大家吃得更好,活得更好,有数亿用户以及丰富的用户行为.随着业务的飞速发展,美团点评的用户和商户数在快速增长.在这样的背景下,通过对推荐算法的优化,可以更好的给用户提供感兴趣的内容,帮用户更快速方便的找到所求.我们目标是根据用户的兴趣及行为

数据结构学习之第7章 树和二叉树

数据结构学习之第7章 树和二叉树 0x7.1.1 树的基本概念 ?1.树的定义 ? 树是由n(n>=0)个结点(或元素)组成的有限集合(记为T) ? 如果n>0,这n个结点中有且仅有一个结点作为树的根结点,简称为根,其余结点可分为m(m>=0)个互不相交的有限集\[T_{1}T_{2}\cdots T_{m}\],其中每个子集又是一棵符合定义的子树,称为根结点的子树. 知识点:由树的定义我们可以看出来树的结构是递归的 ?2.树的逻辑表示法 ? 1.树形表示法 ? 2.文氏图表示法 ? 3

javascript/js实现 排序二叉树数据结构 学习随笔

二叉树是一种数据结构.其特点是: 1.由一系列节点组成,具有层级结构.每个节点的特性包含有节点值.关系指针.节点之间存在对应关系. 2.树中存在一个没有父节点的节点,叫做根节点.树的末尾存在一系列没有子节点的节点,称为叶子节点.其他可以叫做中间节点. 3.树的根节点位于第一层,层级数越大,节点位置越深,层级数也叫做树高. 排序二叉树为二叉树的一种类型,其特点是: 1.节点分为左右子树. 2.在不为空的情况下,左子树子节点的值都小于父节点的值. 3.在不为空的情况下,右子树子节点的值都大于父节点的

java学习-排序二叉树

(排序)二叉树的创建及中序遍历 写起来比C复杂一点,思路大同小异~ 1 package Collection; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 /* 6 * (排序)二叉树的创建及中序遍历 7 */ 8 public class Node { 9 public Node LNode; 10 public Node RNode; 11 public Object value; // 结点的值 12 13 publ