二叉排序树的重要性不用多说,下面用c++实现二叉排序树的建立,插入,查找,修改,和删除。难点在于删除,其他几个相对比较简单。

以下是代码:

 #include<iostream>
using namespace std;
//定义节点
typedef struct BiNode
{
int data;
struct BiNode *lchild,*rchild;
}BiNode,*BiTree; //插入函数
void insertBST(BiTree &T,int key)
{
if(NULL==T)
{
T=new BiNode;
T->data=key;
T->lchild=T->rchild=NULL;
}
else if(T->data==key)
cout<<"不能重复!";
else if(T->data>key)
insertBST(T->lchild,key);
else
insertBST(T->rchild,key); }
//通过插入函数实现创建二叉排序树
void createBST(BiTree &T)
{
int n;
cout<<"请输入要插入的节点数: ";
cin>>n;
int a[n];
cout<<"请输入要插入的数据:中间用空格分开"<<endl;
for(int i=;i<n;i++)
{
cin>>a[i];
insertBST(T,a[i]);
} cout<<"创建二叉排序树完成!"<<endl; } //前序遍历并打印
void preOrderTraverse(BiTree T)
{
if(T)
{
cout <<T->data<< " ";
preOrderTraverse(T->lchild);
preOrderTraverse(T->rchild);
}
}
//中序遍历并打印
void midOrderTraverse(BiTree T)
{ if(T)
{
midOrderTraverse(T->lchild);
cout <<T->data<< " ";
midOrderTraverse(T->rchild);
}
} //定义全局变量layer,表示层数
int layer=;
//下面是查找函数,返回是否查找到数据并且可以确定查找元素的层数
bool searchBST(BiTree &T,int key)
{
layer++;
if(T==NULL)
{
return false;
}
else
{
if (key==T->data)
{ return true; }
else if(key<T->data)
searchBST(T->lchild,key);
else
searchBST(T->rchild,key);
}
}
//利用上面查找函数实现查找操作
void findBST(BiTree &T)
{
int k;
cout<<"请输入要查找的元素值: ";
cin>>k;
if(searchBST(T,k))
{
cout<<"查找成功,该元素位于二叉树中!"<<endl;
cout<<"层数为:"<<layer<<endl;
} else
cout<<"没有查找到该元素!"<<endl;
}
     //定义删除节点的函数
void deletenode(BiTree &p)
{
BiTree q,s; //函数形参P指向要删除的节点,即它的双亲节点的rchild
//根据要删除的节点的孩子情况分三种讨论
//没有左孩子
if(!p->lchild)
{
q=p;
p=p->rchild;
delete q;
}
//没有右孩子
if(!p->rchild)
{
q=p;
p=p->lchild;
delete q; }
//两个孩子都有
else
{
q=p; //q指向上一个节点,s指向下一个节点,即指向q的右孩子,初始时q=p,最终s指向跟p节点换值的那个节点。
s=q->lchild; while(s->rchild)    //通过这个循环实现寻找最接近要删除节点(p)值的节点
{
q=s;
s=s->rchild;
}
p->data=s->data;    //交换值,有个注意事项,s是不存在右孩子的,因为如果存在,则右孩子比他大,更接近p,s需要继续循环,最终s还是没有右孩子。
if(q!=p)          
{
q->rchild=s->lchild;
}
else        //如果q,s 没有移动,即此时q=p,s的初始值就是最接近p点的节点,此时q不存在右节点,需要单独讨论
{
q->lchild=s->lchild;      
}
delete s;
} } //删除操作
bool deleteBST(BiTree &T,int del)
{
if(!T)
return false;
else
{
if(T->data==del)
{
deletenode(T);
return true;
}
else if(del<T->data)
{
return deleteBST(T->lchild,del);
}
else
{
return deleteBST(T->rchild,del);
}
} }

下面是主函数:

 //主函数
int main()
{
BiTree T=NULL;
int d;
createBST(T);
cout<<"前序遍历的结果为:"<<endl;
preOrderTraverse(T);
cout<<endl;
cout<<"中序遍历的结果为:"<<endl;
midOrderTraverse(T);
cout<<endl;
findBST(T);
cout<<"请输入要删除的数据:"<<endl;
cin>>d;
deleteBST(T,d);
cout<<"前序遍历的结果为:"<<endl;
preOrderTraverse(T); }

上面的代码分别实现了查找,建立,插入和删除的操作,删除比较难主要是因为删除节点后下面的所有节点都会受到影响。此时采取的思维是分类讨论节点的孩子节点情况,

最复杂的情况是存在左右孩子,此时有两种思路,对左边孩子树进行操作或者对右边孩子树进行操作,我给出的代码是左边,二者道理一样。具体方法参考代码,说明很详细。

下面给出一个存在双孩子节点的图

画的虽然简陋,但大概意思就这样,(画图的确是理解数据结构的利器啊)最后给出控制台运行结果:

over~

一步一步写数据结构(BST-二叉排序树)的更多相关文章

  1. 一步一步写平衡二叉树(AVL树)

    平衡二叉树(Balanced Binary Tree)是二叉查找树的一个进化体,也是第一个引入平衡概念的二叉树.1962年,G.M. Adelson-Velsky 和 E.M. Landis发明了这棵 ...

  2. 一步一步写算法(之prim算法 上)

    原文:一步一步写算法(之prim算法 上) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 前面我们讨论了图的创建.添加.删除和保存等问题.今 ...

  3. .NET跨平台:在Mac上跟着错误信息一步一步手写ASP.NET 5程序

    今天坐高铁时尝试了一种学习ASP.NET 5的笨方法,从空文件夹开始,根据运行dnx . kestrel命令的错误信息,一步一步写代码,直至将一个最简单的ASP.NET程序运行起来. 尝试的具体步骤如 ...

  4. 《一步一步写嵌入式操作系统》读书笔记1—Skyeye介绍、安装和HelloWorld

    2013-11-14 最近在看<一步一步写嵌入式操作系统>,感觉此书甚好,许多地方讲得很清楚.可操作性强,计划边读边实践边写笔记,希望能够逐步熟悉嵌入式操作系统底层的东西,最终剪裁出一套实 ...

  5. 一步一步写一个简单通用的makefile(三)

    上一篇一步一步写一个简单通用的makefile(二) 里面的makefile 实现对通用的代码进行编译,这一章我将会对上一次的makefile 进行进一步的优化. 优化后的makefile: #Hel ...

  6. Python之美[从菜鸟到高手]--一步一步动手给Python写扩展(异常处理和引用计数)

    我们将继续一步一步动手给Python写扩展,通过上一篇我们学习了如何写扩展,本篇将介绍一些高级话题,如异常,引用计数问题等.强烈建议先看上一篇,Python之美[从菜鸟到高手]--一步一步动手给Pyt ...

  7. 一步一步写算法(之prim算法 下)

    原文:一步一步写算法(之prim算法 下) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 前两篇博客我们讨论了prim最小生成树的算法,熟悉 ...

  8. 一步一步写算法(之prim算法 中)

    原文:一步一步写算法(之prim算法 中) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] C)编写最小生成树,涉及创建.挑选和添加过程 MI ...

  9. 一步一步写算法(之挑选最大的n个数)

    原文:一步一步写算法(之挑选最大的n个数) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 从一堆数据中挑选n个最大的数,这个问题是网上流传的 ...

  10. 一步一步写算法(之n!中末尾零的个数统计)

    原文:一步一步写算法(之n!中末尾零的个数统计) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 在很多面试的题目中,求n!结果中零的个数也是 ...

随机推荐

  1. div内容超出后自动显示滚动条

    一. <div style=" overflow:scroll; width:400px; height:400px;”></div> 记住宽和高一定要设置噢,否则不 ...

  2. 一个简单的ns2实验全过程

    实验名称:比较tcp和udp的丢包行为 试验目的:1. 熟练用ns2做网络仿真试验的整个流程:2. 练习写tcl脚本,了解怎么应用http和rtp:3. 练习用awk处理trace数据,了解怎么计算丢 ...

  3. bzoj 2456: mode ——独特水法

    Description 给你一个n个数的数列,其中某个数出现了超过n div 2次即众数,请你找出那个数. Input 第1行一个正整数n.第2行n个正整数用空格隔开. Output 一行一个正整数表 ...

  4. <!DOCTYPE>是干嘛用的?— html文档类型

    一.啥是文档类型? 在网站开发中一定遇到过这样几种html文档 <!DOCTYPE> 是啥? Web 世界中存在许多不同的文档.只有了解文档的类型,浏览器才能正确地显示文档. HTML 也 ...

  5. 灰色预测 GM11模型

    灰色预测实现见:https://www.jianshu.com/p/a35ba96d852b from pandas import Series from pandas import DataFram ...

  6. 如何在阿里云Centos下安装Nginx

    Nginx("engine x")是一款轻量级的HTTP和反向代理服务器.相比于Apache.lighttpd等,它具有占有内存少.并发能力强.稳定性高等优势.它最常见的用途就是提 ...

  7. 状压dp(B - 炮兵阵地 POJ - 1185 )

    题目链接:https://cn.vjudge.net/contest/276236#problem/B 题目大意:略  具体思路:和我的上一篇写状压dp的思路差不多,不过就是这个题相当于上一个题的升级 ...

  8. mysql中使用日期加减时无法识别年-月格式数据的问题,%Y-%m"这种格式数据

    最新做报表统计的时候处理按月统计部分时发现,虽然使用 DATE_FORMAT( time, '%Y-%m' ) 函数可以将日期格式转成年-月,但是如果是参数是年-月格式,即"2018-10& ...

  9. MySQL 5.7半同步复制after sync和after commit详解【转】

    如果你的生产库开启了半同步复制,那么对数据的一致性会要求较高,但在MySQL5.5/5.6里,会存在数据不一致的风险.有这么一个场景,客户端提交了一个事务,master把binlog发送给slave, ...

  10. 【转载】ajaxFileUpload 报这错jQuery.handleError is not a function

    今天刚打个一个技术群,里面有人问标题上的问题,嘿,我恰好遇过,现在大家至少也在用jquery1.9以上的版本,ajaxfileupload的版本早就不更新了,大家可以下载看:地址这里,它例子里使用的J ...