一步一步写数据结构(BST-二叉排序树)
二叉排序树的重要性不用多说,下面用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-二叉排序树)的更多相关文章
- 一步一步写平衡二叉树(AVL树)
平衡二叉树(Balanced Binary Tree)是二叉查找树的一个进化体,也是第一个引入平衡概念的二叉树.1962年,G.M. Adelson-Velsky 和 E.M. Landis发明了这棵 ...
- 一步一步写算法(之prim算法 上)
原文:一步一步写算法(之prim算法 上) [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 前面我们讨论了图的创建.添加.删除和保存等问题.今 ...
- .NET跨平台:在Mac上跟着错误信息一步一步手写ASP.NET 5程序
今天坐高铁时尝试了一种学习ASP.NET 5的笨方法,从空文件夹开始,根据运行dnx . kestrel命令的错误信息,一步一步写代码,直至将一个最简单的ASP.NET程序运行起来. 尝试的具体步骤如 ...
- 《一步一步写嵌入式操作系统》读书笔记1—Skyeye介绍、安装和HelloWorld
2013-11-14 最近在看<一步一步写嵌入式操作系统>,感觉此书甚好,许多地方讲得很清楚.可操作性强,计划边读边实践边写笔记,希望能够逐步熟悉嵌入式操作系统底层的东西,最终剪裁出一套实 ...
- 一步一步写一个简单通用的makefile(三)
上一篇一步一步写一个简单通用的makefile(二) 里面的makefile 实现对通用的代码进行编译,这一章我将会对上一次的makefile 进行进一步的优化. 优化后的makefile: #Hel ...
- Python之美[从菜鸟到高手]--一步一步动手给Python写扩展(异常处理和引用计数)
我们将继续一步一步动手给Python写扩展,通过上一篇我们学习了如何写扩展,本篇将介绍一些高级话题,如异常,引用计数问题等.强烈建议先看上一篇,Python之美[从菜鸟到高手]--一步一步动手给Pyt ...
- 一步一步写算法(之prim算法 下)
原文:一步一步写算法(之prim算法 下) [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 前两篇博客我们讨论了prim最小生成树的算法,熟悉 ...
- 一步一步写算法(之prim算法 中)
原文:一步一步写算法(之prim算法 中) [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] C)编写最小生成树,涉及创建.挑选和添加过程 MI ...
- 一步一步写算法(之挑选最大的n个数)
原文:一步一步写算法(之挑选最大的n个数) [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 从一堆数据中挑选n个最大的数,这个问题是网上流传的 ...
- 一步一步写算法(之n!中末尾零的个数统计)
原文:一步一步写算法(之n!中末尾零的个数统计) [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 在很多面试的题目中,求n!结果中零的个数也是 ...
随机推荐
- 京东全链路压测军演系统(ForceBot)架构解密
摘要:全链路压测是应对电商大促容量规划最有效的手段,如何有效进行容量规划是其中的架构关键问题.京东在全链路压测方面做过多年尝试,本文转载京东商城基础平台技术专家文章,介绍其最新的自动化压测 Force ...
- 是否使用TDD(测试驱动开发)进行UI开发
问题 StackOverflow上有一则是否使用TDD(测试驱动开发)进行UI开发 的提问. _JacobE_问: 对于是否使用TDD进行开发UI这件事,我想了很久,但难以决定.我想听听你们的意见. ...
- 【转】C# Graphics类详解
Brush 类 .NET Framework 4 定义用于填充图形形状(如矩形.椭圆.饼形.多边形和封闭路径)的内部的对象. 属于命名空间: System.Drawing 这是一个抽象基类,不能进行 ...
- 1.phpcms 伪静态
location / { if (!-f $request_filename){ rewrite (.*) /index.php; } rewrite ^/caipu-([-]+)-([-]+)-([ ...
- 对web标准的理解,以及对w3c组织的认识
(1)web标准规范要求,书写标签必须闭合.标签小写.不乱嵌套,可提高搜索机器人对网页内容的搜索几率.--- SEO(2)建议使用外链css和js脚本,从而达到结构与行为.结构与表现的分离,提高页面的 ...
- 2016.07.15——istringstream测试
istringstream测试 1.istringstream strcin(str),字符串(str)可以包括多个单词,单词之间使用空格分开 #include "stdafx.h" ...
- 2016.6.17——Valid Parentheses
Valid Parentheses 本题收获: 1.stack的使用 2.string和char的区别 题目: Given a string containing just the character ...
- Android获取手机分辨率DisplayMetircs类
关于Android中手机分辨率的使用 Android 可设置为随着窗口大小调整缩放比例,但即便如此,手机程序设计人员还是必须知道手机屏幕的边界,以避免缩放造成的布局变形问题. 手机的分辨率信息是手机的 ...
- 微软Holographic将更名为Windows Mixed Reality
微软Holographic将更名为Windows Mixed Reality ----世界变化好快. 还没来得及细细品味,它就已经更名了. 程序员的焦虑,处在一个信息大爆炸的年代,大数据,云计算,机 ...
- Python3 出现'ascii' codec can't encode characters问题
当使用urllib.request.urlopen打开包含中文的链接时报错: from urllib import request url = 'https://baike.baidu.com/ite ...