基本数据结构 —— 二叉搜索树(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{ ...
随机推荐
- 在CentOS7上部署PostgreSQL11数据库系统
在数据库上的选择,也是基于了稳定性为前提.其实选择的范围并不是太大,基本可以选择的范围也就是SQLServer.MySQL.PostgreSQL这三种.SQL Server是微软的商业数据库,无论是性 ...
- MAVEN项目导入src/test/java项目报错
转载博客:https://blog.csdn.net/gengjianchun/article/details/78679036 https://blog.csdn.net/jsloveyou/ ...
- TeamWork#3,Week5,Scrum Meeting 11.6, 11.7, 11.11, 11.12
11.6:到目前为止基本已完成相关知识的学习,各方面工作都开始进行,一开始进行比较慢. 11.7:项目遇到困难,需要补充相关知识,进度慢了下来. 11.11:各方面工作进展比较顺利,没有什么大问题. ...
- 第二阶段每日站立会议First Day
昨天我进行了用户界面的修改,例如按钮的大小,位置,使界面看起来更美观.更简洁 今天准备安装在手机端进行界面效果测试以及进一步完善 遇到的问题:有些按钮由于在之前固定好的布局之中,所以没法移动其位置
- jsp九大内置对象之config 和 out
jsp中config的作用是读取web.xml中的配置信息,一般在后台获取初始化的参数,jsp页面用的较少因为jsp属于表现层,一般是获取数据. jsp中的out对象是将内容放到缓冲区中然后显示出来
- 作业6 团队项目之需求 (NABCD模型)
N A B C D模型分析 WorkGroup:NewApps 组员:欧其锋(201306114305 http://www.cnblogs.com/ouqifeng/) 吕日荣(20130611 ...
- DPDK skeleton basicfwd 源码阅读
学习这个例子用于理解单纯的 dpdk 转发过程,L2 和 L3 的转发是基于此:在rte_eth_rx_burst()收包后进行解包,提取 mac.ip 等信息然后在转发到输出网卡. 如果要写出自己的 ...
- Unity3D游戏开发——收集当前关卡游戏中分散的物件
运用场景 许多游戏中会有一些供玩家拾起的物件,例如装备.血包.道具等.当玩家与物件进行碰撞后,则会进入仓库. 本篇介绍了简单的碰撞过程. 原理 基本的碰撞机制,用到OnTriggerEnter()碰撞 ...
- Alpha版本冲刺(一)
目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:丹丹 组员7:家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示组内 ...
- Express搭建NodeJS项目
1.安装Node.js: 2.安装npm; 3.安装Express; 在本例中默认全局安装express 安装express生成器 如果没有安装express-generator或安装路径不对,会报以 ...