基本数据结构 —— 二叉搜索树(C++实现)
什么是二叉搜索树
二叉搜索树(英语: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++实现)的更多相关文章
- 数据结构-二叉搜索树(BST binary search tree)
本文由@呆代待殆原创,转载请注明出处:http://www.cnblogs.com/coffeeSS/ 二叉搜索树简介 顾名思义,二叉搜索树是以一棵二叉树来组织的,这样的一棵树可以用一个链表数据结构来 ...
- 数据结构-二叉搜索树的js实现
一.树的相关概念 1.基本概念 子树 一个子树由一个节点和它的后代构成. 节点的度 节点所拥有的子树的个数. 树的度 树中各节点度的最大值 节点的深度 节点的深度等于祖先节点的数量 树的高度 树的高度 ...
- 数据结构☞二叉搜索树BST
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它可以是一棵空树,也可以是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它 ...
- 数据结构---二叉搜索树BST实现
1. 二叉查找树 二叉查找树(Binary Search Tree),也称为二叉搜索树.有序二叉树(ordered binary tree)或排序二叉树(sorted binary tree),是指一 ...
- 数据结构-二叉搜索树和二叉树排序算法(python实现)
今天我们要介绍的是一种特殊的二叉树--二叉搜索树,同时我们也会讲到一种排序算法--二叉树排序算法.这两者之间有什么联系呢,我们一起来看一下吧. 开始之前呢,我们先来介绍一下如何创建一颗二叉搜索树. 假 ...
- 数据结构 - 二叉搜索树封装 C++
二叉搜索树封装代码 #pragma once #include <iostream> using namespace std; template<class T>class T ...
- Java数据结构——二叉搜索树
定义二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若 ...
- 数据结构——二叉搜索树(Binary Search Tree)
二叉树(Binary Tree)的基础下 每个父节点下 左节点小,右节点大. 节点的插入: 若root==NULL则root=newnode 否则不断与节点值比较,较小则向左比较,较大则向右比较. 完 ...
- 数据结构-二叉搜索树Java实现
1,Node.java 生成基础二叉树的结构 package com.cnblogs.mufasa.searchTree; /** * 节点配置父+左+右 */ public class Node{ ...
随机推荐
- 铁轨(rails, ACM/ICPC CERC 1997,Uva 514)
铁轨(rails, ACM/ICPC CERC 1997,Uva 514) 题目描述 某城市有一个火车站,铁轨铺设如图所示.有n节车厢从A方向驶入车站,按进站顺序编号为1~n.你的任务是让它们按照某种 ...
- 虚拟机搭建Hadoop集群
安装包准备 操作系统:ubuntu-16.04.3-desktop-amd64.iso 软件包:VirtualBox 安装包:hadoop-3.0.0.tar.gz,jdk-8u161-linux-x ...
- Beta发布 _thunder_文案+美工展示
作业要求:https://edu.cnblogs.com/campus/nenu/SWE2017FALL/homework/1366 团队介绍:thunder 组成员及各位博客地址: 1.王航:htt ...
- c# 写文件注意问题及用例展示
以txt写string举例,正确代码如下: private void xie() { FileStream fs = new FileStream("1.txt", FileMod ...
- WebGL学习笔记四点二
前几章对图形图形内部多是 以纯色填充,但是现实中已经有许多好的图片了我们没必要一点点画,这一章第五章就是将图片以纹理的形式加载到片元中,主要过程如下,首先是定义点的坐标的attribute变量用于在j ...
- BufferedWriter与BufferedRead --------------------------Test
package com.test; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; ...
- 人and绩效and职业道德
人行走在这个世界上 避免不了的是各种悲哀 人就像是一个茶几 上面放满了各种杯具 而要做的是要么把杯具打碎了咽下去,要么被杯具打晕 本布衣 躬耕于南阳 不求闻达于诸侯 每个人都可以选择自己的生活方式 或 ...
- ssh框架配置数据源 数据库连接没有正常释放
通过多天的改bug 对数据源这个东西了解多了.. 我发现 spring+hibernate下 申请数据库连接是在一个action方法内 也就是说 action 里面有三个 service方 ...
- linshi18
#include<iostream> using namespace std; int n,m,k; #define max 100 char mmap[max][max]; int mm ...
- week3c:个人博客作业
程序测试: 一个基本的测试. 在Visual Studio 2013 中使用C++单元测试 操作如下: 这是我学到的过程. 有复杂程序的测试.以后有时间再弄.