暂未发现什么bug,如果发现请指出。

#include<iostream>
using namespace std;
//定义二叉搜索树的结点
struct Node
{
    int data;
    Node *lc,*rc,*parent;
};
//中序遍历二叉搜索树
void show(Node *now)
{
    if(now==NULL) return;
    show(now->lc);
    cout<<now->data<<endl;
    show(now->rc);
}
//将值为val的结点插入到二叉搜索树中
//?为什么要传指向根结点指针的指针,而不是直接传根结点的指针。因为根结点的指针可能为空,这里需要开辟内存。
Node* insert(Node **rt,int val)
{
    Node *now=*rt;//用now指针在树上移动
    Node *par=NULL;//记录now指针的父亲
    while(now!=NULL)
    {
        par=now;
        if(val<now->data)//如果val小于当前结点的值说明应该插到左子树中
            now=now->lc;
        else
            now=now->rc; //否则插入到右子树中
    }
    Node *newnode=new Node;//开辟新结点
    newnode->data=val;
    newnode->lc=newnode->rc=NULL;
    if(par==NULL)//当这是一棵空树的时候
    {
        newnode->parent=NULL;
        *rt=newnode;//直接通过指针修改根结点
    }
    else
    {
        if(val<par->data)
            par->lc=newnode;
        else
            par->rc=newnode;
        newnode->parent=par;
    }
    return newnode;
}
//在以now为根结点的树上,寻找值为val的结点
Node* search(Node *now,int val)
{
    while(now!=NULL&&now->data!=val)
    {
        if(val<now->data)
            now=now->lc;
        else
            now=now->rc;
    }
    return now;
}
//在以now为根结点的树上,寻找最大、最小值
Node* maximun(Node *now)
{
    while(now->rc!=NULL)
    {
        now=now->rc;
    }
    return now;
}
Node* minimun(Node *now)
{
    while(now->lc!=NULL)
        now=now->lc;
    return now;
}
//寻找now结点的前继、后继
//寻找前继:如果now的左子树非空,则返回左子树的最大值结点。否则如果now是父亲的左孩子则不断向上直到now不再是父亲的左孩子,返回父结点。
Node* predecessor(Node *now)
{
    if(now->lc!=NULL)
        return maximun(now->lc);
    Node *par=now->parent;
    while(par!=NULL&&now==par->lc)
    {
        now=par;
        par=par->parent;
    }
    return par;
}
Node* successor(Node *now)
{
    if(now->rc!=NULL)
        return minimun(now->rc);
    Node *par=now->parent;
    while(par!=NULL&&now==par->rc)
    {
        now=par;
        par=par->parent;
    }
    return par;
}
//对于一棵以T为根结点的树,用以v为根结点的子树取代以u为根结点的子树,完成u的父亲与v之间的绑定
void transplant(Node **T,Node *u,Node *v)
{
    if(u->parent==NULL)
        (*T)=v;
    else if(u==u->parent->lc)
        u->parent->lc=v;
    else if(u==u->parent->rc)
        u->parent->rc=v;
    if(v!=NULL)
        v->parent=u->parent;
}
//删除给定结点
void erase(Node **T,Node *now)
{
    Node *temp=now;
    if(now->lc==NULL)
    {
        transplant(T,now,now->rc);
    }
    else if(now->rc==NULL)
    {
        transplant(T,now,now->lc);
    }
    else
    {
        Node* nextnode=successor(now);
        if(nextnode!=now->rc)
        {
            transplant(T,nextnode,nextnode->rc);
            nextnode->rc=now->rc;
            now->rc->parent=nextnode;
        }
        transplant(T,now,nextnode);

        nextnode->lc=now->lc;
        now->lc->parent=nextnode;
    }
    delete temp;
}
int main()
{
    Node *root=NULL;
    )
    {
        cout<<"1.插入结点"<<endl;
        cout<<"2.删除结点"<<endl;
        cout<<"3.中序遍历"<<endl;
        cout<<"4.查询"<<endl;
        cout<<"5.查询根"<<endl;
        int p;
        cin>>p;
        )
        {
            cout<<"输入待插元素值:"<<endl;
            int t;
            cin>>t;
            insert(&root,t);
            cout<<"插入成功!"<<endl;
        }
        )
        {
            cout<<"输入待删元素值:"<<endl;
            int t;
            cin>>t;
            Node *q=search(root,t);
            if(q==NULL)cout<<"该值不存在!"<<endl;
            else
            {
                erase(&root,q);
                cout<<"删除成功!"<<endl;
            }
        }
        )
        {
            cout<<"======"<<endl;
            show(root);
            cout<<"======"<<endl;
        }
        )
        {
            cout<<"输入待查询元素值:"<<endl;
            int t;
            cin>>t;
            Node *q=search(root,t);
            if(q==NULL) cout<<"该值不存在!"<<endl;
            else
            {
                Node *a=predecessor(q),*b=successor(q);
                if(a!=NULL)
                    cout<<"前继:"<<a->data<<endl;
                if(b!=NULL)
                    cout<<"后继:"<<b->data<<endl;
            }
        }
        )
        {
            if(root==NULL) cout<<"根为空!"<<endl;
            else cout<<"根:"<<root->data<<endl;
        }
    }
    ;
}

二叉搜索树 C++代码实现的更多相关文章

  1. python 二叉搜索树相关代码

    class TreeNode: def __init__(self, val): self.val = val self.left = None self.right = None class Ope ...

  2. 基于visual Studio2013解决算法导论之029二叉搜索树

     题目 二叉搜索树 解决代码及点评 #include <stdio.h> #include <malloc.h> #include <stdlib.h> ty ...

  3. 二叉搜索树(Binary Search Tree)--C语言描述(转)

    图解二叉搜索树概念 二叉树呢,其实就是链表的一个二维形式,而二叉搜索树,就是一种特殊的二叉树,这种二叉树有个特点:对任意节点而言,左孩子(当然了,存在的话)的值总是小于本身,而右孩子(存在的话)的值总 ...

  4. 自己动手实现java数据结构(六)二叉搜索树

    1.二叉搜索树介绍 前面我们已经介绍过了向量和链表.有序向量可以以二分查找的方式高效的查找特定元素,而缺点是插入删除的效率较低(需要整体移动内部元素):链表的优点在于插入,删除元素时效率较高,但由于不 ...

  5. 数据结构 - 二叉搜索树封装 C++

    二叉搜索树封装代码 #pragma once #include <iostream> using namespace std; template<class T>class T ...

  6. 每日一题 - 剑指 Offer 33. 二叉搜索树的后序遍历序列

    题目信息 时间: 2019-06-26 题目链接:Leetcode tag:分治算法 递归 难易程度:中等 题目描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果.如果是则返回 tr ...

  7. 编程算法 - 二叉搜索树 与 双向链表 代码(C++)

    二叉搜索树 与 双向链表 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 题目:输入一颗二叉搜索树, 将该二叉搜索树转换成一个排序的双向链表. 要求 ...

  8. 编程算法 - 二叉搜索树(binary search tree) 代码(C)

    二叉搜索树(binary search tree) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 二叉搜索树(binary search tree)能 ...

  9. BinarySearchTree(二叉搜索树)原理及C++代码实现

    BST是一类用途极广的数据结构.它有如下性质:设x是二叉搜索树内的一个结点.如果y是x左子树中的一个结点,那么y.key<=x.key.如果y是x右子树中的一个结点,那么y.key>=x. ...

随机推荐

  1. maven、strutst版本号

    struts.2.3.15.3 :大版本号 struts1-->struts2 :分支版本号 增加新功能 :小版本号 修复bug beta:公测版release:发行版(已可以使用)Genera ...

  2. artTemplate模板引擎

    artTemplate模板引擎         <li>索引 {{i + 1}} :{{value}}</li>     {{/each}} </ul> </ ...

  3. CSS3响应式布局之弹性盒子

    CSS3弹性盒模型可以轻松的创建自适应浏览器流动窗口的布局或自适应字体大小的布局.同时该盒子决定了一个盒子在其他盒子的分布方式,及如何处理可用的空间. 自己写了一个弹性盒子的demo: 主要HTML代 ...

  4. UDP:用户数据报协议

    UDP是一个简单的面向数据报的运输层协议:进程的每个输出操作都正好产生一个UDP数据报,并组装成一份待发送的IP数据报.这与面向流字符的协议不同,如TCP,应用程序产生的全体数据与真正发送的单个IP数 ...

  5. LA 3713 宇航员分组

    题目链接:http://vjudge.net/contest/142615#problem/B 题意:有A,B,C三个人物要分配个N个宇航员,每个宇航员恰好要分配一个任务,设平均年龄为X,只有年龄大于 ...

  6. AC自动机——Uva 11468 子串

    题目链接:http://vjudge.net/contest/142513#problem/A 题意:给出一些字符和各自对应的选择概率,随机选择L次后将得到一个长度为L的随机字符串S.给出K个模版串, ...

  7. A feature in Netsuite Reports > Financial > Balance Sheet

    最新版本的Customize balance sheet page Left side > Layout > Add Reference Row Then in right side, y ...

  8. chrome 开发者工具详解

    Google Chrome一共提供了8大组工具: Elements: 允许我们从浏览器的角度看页面,也就是说我们可以看到chrome渲染页面所需要的的HTML.CSS和DOM(Document Obj ...

  9. 8 个必备的PHP功能开发

    做过PHP开发的程序员应该清楚,PHP中有很多内置的功能,掌握了它们,可以帮助你在做PHP开发时更加得心应手,本文将分享8个开发必备的PHP功能,个个都非常实用,希望各位PHP开发者能够掌握.    ...

  10. 13.KVM安装之网桥

    安装必须的几个库和软件(最好下载一个163的yum源,速度快点) $ yum -y install kvm python-virtinst libvirt tunctl bridge-utils vi ...