什么是二叉搜索树

二叉搜索树(英语:Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树:

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左、右子树也分别为二叉搜索树。

二叉搜索树如何储存数值

如图所示:



所有的节点,都满足左子树上的所有节点都比自己的小,而右子树上的所有节点都比自己大这个条件。

二叉搜索树的操作

因为二叉搜索树的性质,二叉搜索树能够高效地进行如下操作:

  • 插入一个数值;
  • 查询是否包含某个数值;
  • 删除某个数值

如果共有n个元素,那么平均每次操作需要O(logn)的时间。

接下来用C++来实现以上操作。首先定义节点结构体如下:

node* insert(node* p,int x)
{
if(!p)
{
auto q = new node(x);
return q;
}
else
{
if(x < p->val) p->lch = insert(p->lch,x);
else p->rch = insert(p->rch,x);
return p;
}
}

插入一个数值

如图所示:

node* insert(node* p,int x)
{
if(!p) //空树
{
auto q = new node(x);
return q;
}
else
{
if(x < p->val) p->lch = insert(p->lch,x);
else p->rch = insert(p->rch,x);
return p;
}
}

查询是否包含某个数值

如图所示:

bool find(node* p,int x)
{
if(!p) return false;
if(x == p->val) return true;
if(x < p->val) return find(p->lch,x);
else return find(p->rch,x);
}

删除某个数值

数值的删除比起之前提到的操作要稍微麻烦一些。例如,我们要删除数值15。如果删除了15所在的节点,那么它的两个儿子10和17就悬空了。于是,把11提到15所在的位置就可以解决问题。如图所示:



一般来说,需要根据下面几种情况分别进行处理:

  • 需要删除的节点没有左儿子,那么就把右儿子提上去。
  • 需要删除的节点的左儿子没有右儿子,那么就把左儿子提上去。
  • 以上两种情况都不满足的话,就把左儿子的子孙中最大的节点提到需要删除的节点上。
node* remove(node* p,int x)
{
if(!p) return NULL;
if(x < p->val) p->lch = remove(p->lch,x);
else if(x > p->val) p->rch = remove(p->rch,x);
else
{
if(p->lch == NULL) //需要删除的节点没有左儿子
{
auto q = p->rch;
delete p;
return q;
}
else if(p->lch->rch == NULL) //需要删除的节点的左儿子没有右儿子
{
auto q = p->lch;
q->rch = p->rch;
delete p;
return q;
}
else
{
auto q = p->lch;
while(q->rch->rch != NULL) q = q->rch;
auto r = q->rch;
q->rch = r->lch;
r->lch = p->lch;
r->rch = p->rch;
delete p;
return r;
}
return p;
}
}

测试代码

#include<iostream>
#include<algorithm>
#include<queue> using namespace std; struct node{
int val;
node *lch,*rch;
node(int value): val(value),lch(NULL),rch(NULL){ }
};
node* insert(node* p,int x)
{
if(!p)
{
auto q = new node(x);
return q;
}
else
{
if(x < p->val) p->lch = insert(p->lch,x);
else p->rch = insert(p->rch,x);
return p;
}
}
bool find(node* p,int x)
{
if(!p) return false;
if(x == p->val) return true;
if(x < p->val) return find(p->lch,x);
else return find(p->rch,x);
}
node* remove(node* p,int x)
{
if(!p) return NULL;
if(x < p->val) p->lch = remove(p->lch,x);
else if(x > p->val) p->rch = remove(p->rch,x);
else
{
if(p->lch == NULL) //需要删除的节点没有左儿子
{
auto q = p->rch;
delete p;
return q;
}
else if(p->lch->rch == NULL) //需要删除的节点的左儿子没有右儿子
{
auto q = p->lch;
q->rch = p->rch;
delete p;
return q;
}
else
{
auto q = p->lch;
while(q->rch->rch != NULL) q = q->rch;
auto r = q->rch;
q->rch = r->lch;
r->lch = p->lch;
r->rch = p->rch;
delete p;
return r;
}
return p;
}
}
void printTree(node* root)
{
queue<node*> q;
q.push(root);
while(!q.empty())
{
auto p = q.front();q.pop();
if(p)
{
cout << p->val << " ";
q.push(p->lch);
q.push(p->rch);
}
}
cout << endl;
}
int main() {
node* root = insert(NULL,7);
insert(root,2);
insert(root,15);
insert(root,1);
insert(root,5);
insert(root,10);
insert(root,17);
insert(root,4);
insert(root,6);
insert(root,8);
insert(root,11);
insert(root,16);
insert(root,19);
if(find(root,15)) cout << "find 15" << endl;
else cout << "can not find 15" << endl;
if(find(root,3)) cout << "find 3" << endl;
else cout << "can not find 3" << endl;
printTree(root);
remove(root,15);
printTree(root);
return 0;
};

结果:

参考资料

基本数据结构 —— 二叉搜索树(C++实现)的更多相关文章

  1. 数据结构-二叉搜索树(BST binary search tree)

    本文由@呆代待殆原创,转载请注明出处:http://www.cnblogs.com/coffeeSS/ 二叉搜索树简介 顾名思义,二叉搜索树是以一棵二叉树来组织的,这样的一棵树可以用一个链表数据结构来 ...

  2. 数据结构-二叉搜索树的js实现

    一.树的相关概念 1.基本概念 子树 一个子树由一个节点和它的后代构成. 节点的度 节点所拥有的子树的个数. 树的度 树中各节点度的最大值 节点的深度 节点的深度等于祖先节点的数量 树的高度 树的高度 ...

  3. 数据结构☞二叉搜索树BST

    二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它可以是一棵空树,也可以是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它 ...

  4. 数据结构---二叉搜索树BST实现

    1. 二叉查找树 二叉查找树(Binary Search Tree),也称为二叉搜索树.有序二叉树(ordered binary tree)或排序二叉树(sorted binary tree),是指一 ...

  5. 数据结构-二叉搜索树和二叉树排序算法(python实现)

    今天我们要介绍的是一种特殊的二叉树--二叉搜索树,同时我们也会讲到一种排序算法--二叉树排序算法.这两者之间有什么联系呢,我们一起来看一下吧. 开始之前呢,我们先来介绍一下如何创建一颗二叉搜索树. 假 ...

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

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

  7. Java数据结构——二叉搜索树

    定义二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若 ...

  8. 数据结构——二叉搜索树(Binary Search Tree)

    二叉树(Binary Tree)的基础下 每个父节点下 左节点小,右节点大. 节点的插入: 若root==NULL则root=newnode 否则不断与节点值比较,较小则向左比较,较大则向右比较. 完 ...

  9. 数据结构-二叉搜索树Java实现

    1,Node.java 生成基础二叉树的结构 package com.cnblogs.mufasa.searchTree; /** * 节点配置父+左+右 */ public class Node{ ...

随机推荐

  1. ASN.1编码方式详解

    ASN ASN.1 – Abstract Syntax Notation dot one,抽象记法1.数字1被ISO加在ASN的后边,是为了保持ASN的开放性,可以让以后功能更加强大的ASN被命名为A ...

  2. python3安装与环境配置和pip的基本使用

    本文环境 系统: Windows10 Python版本: 3.6 安装 python安装包下载 可以选择安装版和解压版 安装版一键安装, 安装过程注意选择安装位置, xx To Path选项(勾选), ...

  3. python破解网吧收费系统,远控网吧电脑设备!

      我今天呢 , 我就没事跟着朋友喝酒喝酒啊.喝了很多啊.晚上到旁边的酒店开了一个房间,到了酒店才十点! 感觉没啥事情干的,那就去网吧走走看把,看到是一个嘟嘟牛的,和上次是一样的.还是照常用MS170 ...

  4. Netty源码分析第2章(NioEventLoop)---->第1节: NioEventLoopGroup之创建线程执行器

    Netty源码分析第二章: NioEventLoop 概述: 通过上一章的学习, 我们了解了Server启动的大致流程, 有很多组件与模块并没有细讲, 从这个章开始, 我们开始详细剖析netty的各个 ...

  5. Influxdb配置文件详解---influxdb.conf

    官方介绍:https://docs.influxdata.com/influxdb/v1.2/administration/config/ 全局配置 1 2 reporting-disabled =  ...

  6. django1.11入门

    快速安装指南¶ 在使用Django之前,您需要安装它.我们有 完整的安装指南,涵盖所有可能性; 本指南将指导您进行简单,最小化的安装,在您完成介绍时可以正常工作. 安装Python¶ 作为一个Pyth ...

  7. DevOps on AWS之OpsWorks初体验

    AWS OpsWorks 是一款配置管理服务,提供 Chef 和 Puppet 的托管EC2虚拟机实例.Chef 和 Puppet 是自动化平台,允许用户使用代码来自动配置服务器.用户借助OpsWor ...

  8. DenseNet——Densely Connected Convolutional Networks

    1. 摘要 传统的 L 层神经网络只有 L 个连接,DenseNet 的结构则有 L(L+1)/2 个连接,每一层都和前面的所有层进行连接,所以称之为密集连接的网络. 针对每一层网络,其前面所有层的特 ...

  9. PLSQL Developer windows 64位连接数据库的问题

    使用PLSQL Developer 工具连接到数据库进行开发,目前主流windows 系统都是64位操作系统,而PLSQL Developer  只有32位程序,所以在连接数据库上遇到一些问题. PL ...

  10. OO学习第二阶段总结

    面向对象课程的第二个阶段结束了,作业们由简单的玩具模式步入到复杂的多线程地狱模式,由之前的算法简单实现有坑转变成算法复杂实现有很大的坑.一个最重要的心得就是一定要在动手敲代码实现之前对整个程序的实现做 ...