body, table{font-family: 微软雅黑; font-size: 13.5pt}
table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;}
th{border: 1px solid gray; padding: 4px; background-color: #DDD;}
td{border: 1px solid gray; padding: 4px;}
tr:nth-child(2n){background-color: #f8f8f8;}

二叉排序树(Binary Sort Tree):
  又叫做二叉查找树。它或者是一棵空树,或者是具有下列性质的二叉树。
   ■ 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值
   ■ 若它的右子树不空,则右子树上所有结点的值均大于它的根节点的值
   ■ 它的左、右子树也分别为二叉排序树
{62,88,58,47,35,73,51,99,37,93}


构造二叉树的目的是为了提高查找和插入、删除关键字的速度。

二叉排序树删除结点的三种情况:
   ■ 叶子结点(直接删除)
   ■ 仅有左或右子树的结点(左子树或右子树替换删除节点)
   ■ 左右子树都有的结点(中序遍历前驱或后继取代该结点)
/* BST.h */

#ifndef __BST_H__
#define __BST_H__
#include<iostream>
using namespace std;
typedef struct Binary_Sort_Tree
{
        int data;
        struct Binary_Sort_Tree* lchild,*rchild;
}bstNode,*pBstNode;
void BST_Insert(pBstNode& root,int data);  //二叉排序树中插入结点
bstNode* BST_Search(pBstNode root,int key);  //二叉排序树中查找关键字key
int deleteNode(bstNode*& node);  //删除节点node,形参为待删除节点的地址本身
int BST_Delete(pBstNode& root,int key);   //二叉树删除关键字key  //成功返回
/*  二叉搜索树的三种遍历  */
void preorderTraversal_BST(const pBstNode& root);
void inorderTraversal_BST(const pBstNode& root);
void postorderTraversal_BST(const pBstNode& root);
#endif

/* testmain.cpp */
#include"BST.h"
void test()
{
        int a[10] = {62,88,58,47,35,73,51,99,37,93};
        pBstNode root = nullptr;  //建立二叉搜索树
        for(int idx=0;idx!=10;++idx)
        {
                BST_Insert(root,a[idx]);
        }
        for(int idx=0;idx!=10;++idx)
        {
                bstNode* ret = BST_Search(root,a[idx]);
                if(nullptr!=ret)
                        cout<<ret->data<<" ";
        }
        cout<<endl;
        cout<<"二叉排序树的三种遍历:"<<endl;
        cout<<"前序遍历:";
        preorderTraversal_BST(root);
        cout<<endl;
        cout<<"中序遍历:";
        inorderTraversal_BST(root);
        cout<<endl;
        cout<<"后序遍历:";
        postorderTraversal_BST(root);
        cout<<endl<<endl;
        for(int idx=0;idx!=10;++idx)
        {
                cout<<"删除"<<a[idx]<<endl;
                int ret = BST_Delete(root,a[idx]);
                if(-1==ret)
                        cout<<"BST_Delete "<<a[idx]<<" fail!"<<endl;
                cout<<"前序遍历:";
                preorderTraversal_BST(root);
                cout<<endl;
                cout<<"中序遍历:";
                inorderTraversal_BST(root);
                cout<<endl;
                cout<<"后序遍历:";
                postorderTraversal_BST(root);
                cout<<endl;
        }
        cout<<endl;
}
int main()
{
        test();
        system("pause");
}

/* BST.cpp */

#include"BST.h"
bstNode* BST_Search(pBstNode root,int key)  //二叉排序树中查找关键字key
{
        if(nullptr==root)
                return nullptr;
        if(root->data==key)
        {
                return root;
        }
        else if(key>root->data)  //大于根结点,右子树中继续查找
        {
                BST_Search(root->rchild,key); 
        }
        else if(key<root->data)  //小于根结点,做左子树中继续查找
        {
                BST_Search(root->lchild,key);
        }
} 
void BST_Insert(pBstNode& root,int data)  //二叉排序树中插入结点
{
        if(nullptr==root)
        {
                root = new bstNode();
                root->lchild = root->rchild = nullptr;
                root->data = data;
                return ;
        }
        //遍历二叉排序树,找到待插入节点数据的位置
        bstNode* parentNode = nullptr;  //parentNode永远指向data待插入位置的父结点
        bstNode* curNode = root;
        while(nullptr!=curNode)
        {
                parentNode = curNode;
                if(data>curNode->data)
                        curNode = curNode->rchild;  //应该插入到右子树
                else if(data<=curNode->data)  
                        curNode = curNode->lchild;  //应该插入到左子树
        }
        //找到插入位置
        if(data>parentNode->data)
        {
                bstNode* newNode = new bstNode();
                newNode->data = data;
                newNode->lchild = nullptr;
                newNode->rchild = nullptr;
                parentNode->rchild = newNode;  //插入到右子树
                return ;
        }
        else
        {
                bstNode* newNode = new bstNode();
                newNode->data = data;
                newNode->lchild = nullptr;
                newNode->rchild = nullptr;
                parentNode->lchild = newNode;  //插入到左子树
                return ;
        }
}
int deleteNode(bstNode*& node)
{//二叉搜索树删除,node的前驱替换
        if(nullptr==node)
                return -1;
        bstNode* delNode = node;  //暂存要删除节点
        //1、只有一个结点
        if(nullptr==node->lchild && nullptr==node->rchild)
        {
                node = nullptr;  //前面这些情况为什么能直接改nullptr?
                //下面递归传值的时候传的是root->lchild或者root->rchild,所能是对父结点的左右指针修改。
                //而不是类似这种node1(lchild,data,adrnode2)->node2(lchild,data,lchild2),然后传node2,把node2=nullptr,这样到时候遍历根结点就会根据一个野指针adrnode2访问到脏数据
                delete delNode;
                return 0;
        }
        //2、只有左孩子,重接左孩子就好
        else if (nullptr==node->rchild)
        {
                node = node->lchild;
                delete delNode;
                return 0;
        }
        //3、只有右孩子
        else if(nullptr==node->lchild)
        {
                node = node->rchild;
                delete delNode;
                return 0;
        }
        //4、左右孩子都有
        else if(nullptr!=node->lchild && nullptr!=node->rchild)
        {  //找前驱
                bstNode* parent = delNode;  //记录父结点
                delNode = delNode->lchild;
                //待删除节点delNode没有右子树,前驱就是delNode
                if(nullptr==delNode->rchild)
                {
                        node->data = delNode->data;
                        node->lchild = delNode->lchild;
                        delete delNode;
                        delNode = nullptr;
                        return 0;
                }
                //有右子树,前驱是右子树的最右结点
                while(nullptr!=delNode->rchild)
                {
                        parent = delNode;
                        delNode = delNode->rchild;
                }
                //找到前驱,开始替换,只要替换结点数据即可,左右孩子关系不能更改
                node->data = delNode->data;
                //判断前驱是不是要用其他结点替换
                parent->rchild = delNode->lchild;
                delete delNode;
                delNode = nullptr;
                return 0;
        }
        return 0;
}

int BST_Delete(pBstNode& root,int key)  //二叉树删除关键字key
{
        if(nullptr==root)
                return -1;
        if(key==root->data)
        {
                return deleteNode(root);
        }
        else if(key>root->data)
                return BST_Delete(root->rchild,key);  //右子树中查找删除
        else if(key<root->data)
                return BST_Delete(root->lchild,key);
}
/*  二叉搜索树的三种遍历  */
void preorderTraversal_BST(const pBstNode& root)
{
        if(nullptr==root)
                return;
        cout<<root->data<<" ";
        preorderTraversal_BST(root->lchild);
        preorderTraversal_BST(root->rchild);
}
void inorderTraversal_BST(const pBstNode& root)
{
        if(nullptr==root)
                return;
        inorderTraversal_BST(root->lchild);
        cout<<root->data<<" ";
        inorderTraversal_BST(root->rchild);
}
void postorderTraversal_BST(const pBstNode& root)
{
        if(nullptr==root)
                return;
        inorderTraversal_BST(root->lchild);
        inorderTraversal_BST(root->rchild);
        cout<<root->data<<" ";
}

二叉排序树,Binary_Sort_Tree,C++完整实现的更多相关文章

  1. 算法与数据结构(十) 二叉排序树的查找、插入与删除(Swift版)

    在上一篇博客中,我们主要介绍了四种查找的方法,包括顺序查找.折半查找.插入查找以及Fibonacci查找.上面这几种查找方式都是基于线性表的查找方式,今天博客中我们来介绍一下基于二叉树结构的查找,也就 ...

  2. 数据结构图文解析之:树的简介及二叉排序树C++模板实现.

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  3. 二叉查找树 C++实现(含完整代码)

    一般二叉树的查找是通过遍历整棵二叉树实现,效率较低.二叉查找树是一种特殊的二叉树,可以提高查找的效率.二叉查找树又称为二叉排序树或二叉搜索树. 二叉查找树的定义 二叉排序树(Binary Search ...

  4. c/c++ 二叉排序树

    c/c++ 二叉排序树 概念: 左树的所有节点的值(包括子节点)必须小于中心节点,右树所有节点的值(包括子节点)必须大于中心节点. 不允许有值相同的节点. 二叉排序树的特点: 中序遍历后,就是从小到大 ...

  5. AVL平衡二叉树实现,图解分析,C++描述,完整可执行代码

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  6. 【Java】 大话数据结构(11) 查找算法(2)(二叉排序树/二叉搜索树)

    本文根据<大话数据结构>一书,实现了Java版的二叉排序树/二叉搜索树. 二叉排序树介绍 在上篇博客中,顺序表的插入和删除效率还可以,但查找效率很低:而有序线性表中,可以使用折半.插值.斐 ...

  7. 二叉排序树的理解和实现(Java)

    二叉排序树的定义和性质 二叉排序树又称二叉排序树.它或者是一个空树,或者是一个具有下列性质的二叉树: 若它的左子树不空,则左子树上所有节点的值均小于它的根结构的值 若它的右子树不空,则右子树上所有结点 ...

  8. 【LeetCode-面试算法经典-Java实现】【109-Convert Sorted List to Binary Search Tree(排序链表转换成二叉排序树)】

    [109-Convert Sorted List to Binary Search Tree(排序链表转换成二叉排序树)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 ...

  9. 数据结构与算法—二叉排序树(java)

    前言 前面介绍学习的大多是线性表相关的内容,把指针搞懂后其实也没有什么难度.规则相对是简单的. 再数据结构中树.图才是数据结构标志性产物,(线性表大多都现成api可以使用),因为树的难度相比线性表大一 ...

随机推荐

  1. Codeforces 488B - Candy Boxes

    B. Candy Boxes 题目链接:http://codeforces.com/problemset/problem/488/B time limit per test 1 second memo ...

  2. 第 8 章 容器网络 - 058 - flannel 概述

    flannel 概述 flannel 是 CoreOS 开发的容器网络解决方案. flannel 为每个 host 分配一个 subnet,容器从此 subnet 中分配 IP,这些 IP 可以在 h ...

  3. Python pickle使用

    2019-01-15 10:04:32 用于序列化的两个模块 json:用于字符串和Python数据类型间进行转换 pickle: 用于python特有的类型和python的数据类型间进行转换 jso ...

  4. linux yum+wget详解

    在做自动化测试的时候,有个test需要执行命令:wget http://www.aliyun.com,但是返回的结果是未找到命令wget,于是百度了相关资料,发现没有安装wget,于是利用yum in ...

  5. python中装饰器

    在介绍装饰器之前,要先了解装饰器的相关基础知识. 嵌套函数: 最后引入一个基本的装饰器的例子: __author__ = "YanFeixu" import time def ti ...

  6. jenkins之从0到1利用Git和Ant插件打war包并自动部署到tomcat(第一话):初次启动jenkins,输入给定密码后登录失败问题解决

    Jenkins是一个持续集成平台,它能够从git等源码管理服务器拉取代码.打包并发布到tomcat等中间件,只要配置好相关插件,就可以做到项目的自动化构建.部署,不论是对开发来说监控代码质量,还是对测 ...

  7. JFinal3.0 sql管理与动态生成

    原文: 本节学习目标主要是使用JFinal中自带的Template Engin来实现对sql的管理.JFinal中为sql管理提供了3个指令#sql.#para.#namespace,来增强sql功能 ...

  8. HeadFIrst Ruby 第七章总结 hashes

    前言 这一章节介绍了 Ruby 中 hash 这一数据类型的用法和特征. Hash 的定义 与 array 的对比 最大的不同: An array can only use integers as i ...

  9. Arduino 数字函数总结

    Arduino 有三个数字函数,分别是:pinMode( ), digitalWrite( ),digitalRead( ).三个函数各有其作用,pinMode( ) 在初始化 setup( )函数中 ...

  10. 练习:将从表读出来的时间戳除以1000(java读时间戳会多出3个000)用jackson包 实现

    练习:将从表读出来的时间戳除以1000(java读时间戳会多出3个000)jackson包 实现 entity @Entity @DynamicUpdate //自动更新日期 @Data //get/ ...