数据结构:二叉查找树(C语言实现)
数据结构:二叉查找树
二叉查找树
基础知识
关于二叉树的基础知识,请看我的一篇博客:二叉树的链式存储

二叉查找树的特征
二叉查找树或者是一棵空树,或者是具有下列性质的二叉树:
1.若其左子树不空,则左子树上所有结点的值均小于它的根结点的值;
2.若其右子树不空,则右子树上所有结点的值均大于它的根结点的值;
3.其左、右子树也分别为二叉排序树
二叉查找树的建立
反复插入节点所构造出来的!若二叉树为空树,则插入元素作为树根节点。若根结点的键值等于key,则插入失败;若key小于根结点的键值,则插入到根的左子树上;否则,插入到根的右子树上新插入的节点一定是一个叶子节点!
代码分析
void InsertBST(BiStree &Tree,ElemType e)
{
BiStree T =Tree; //定义执行副本,!
BiStree father =NULL; //定义
while (T&&T->data.key!=e.key)
{
father=T;
if(e.key>T->data.key)
T=T->Rchild;
else
T=T->Lchild;
}
if(T) //跳出循环的只有两种情况,要么就是T不存在,要么就是找到了对应元素!T 存在说明,只能是对应元素也存在,那我我们就不用插入了
return;
BiSnode *s = (BiSnode*)malloc(sizeof(BiSnode));//能到这里,说明节点不存在,新建一个节点,并初始化!
s->data=e;
s->Rchild=s->Lchild=NULL; if(father==NULL) //如果farther不存在,那说明就是没有执行While语句,也即是树是空的,因为一旦执行,就不会为NULL!
Tree=s;
else if(e.key>father->data.key) //到这里说明Farther存在,那么剩下的就是往farther左右节点插入元素了
father->Rchild=s;
else
father->Lchild=s;
}
删除运算
删除运算是的基础是查找元素,首先要查找要删除的元素,如果找到就删除,找不到就不用删除了。
查找代码
void DelBST(BiStree &Tree,char key)
{
if(!Tree) //如果节点为空节点,说明要删除的元素不可能存在,所以返回就好!
return;
else //下面是节点存在的分情况判断:
{
if(Tree->data.key==key) //如果找到了要删除的节点!
{
deleteNode(Tree); //删除该节点
}
else if(Tree->data.key<key) //如果要删除的节点大于该节点,则往该节点的右子树方向进行查找
DelBST(Tree->Rchild,key);
else
DelBST(Tree->Lchild,key);//如果要删除的节点小于该节点,则往该节点的左子树方向进行查找
}
}
到现在我们已经找到元素了 ,要对其删除,就是要实现deleteNode(Tree);方法!
但是删除元素的运算是存在多种情况的,我们要分别处理:
★待删除的结点*p是个叶子结点

★待删除的结点*p是仅有一个非空子树

★待删除的结点*p有两个非空子树

如何找出直接前驱:找到要删除节点的第一个左子树然后一直向右!
删除代码
void deleteNode(BiStree &p)
{
if(!p->Rchild) //对第一种及第二种情况的处理
{
BiSnode * q =p;
p=p->Lchild;
free(q);
}
else if(!p->Lchild) //对第一种及第二种情况的处理
{
BiSnode * q =p;
p=p->Rchild;
free(q);
} else
{
BiSnode * q =p;
BiSnode * s =p->Lchild;
while (s->Rchild)
{
q=s;
s=s->Rchild;
}
//s指向被删节点p的前驱
p->data=s->data;
if(q!=p) //详见下两图
q->Rchild=s->Lchild; //左图
else
q->Lchild=s->Lchild; //右图
free(s);
} }


数据结构:二叉查找树(C语言实现)的更多相关文章
- 数据结构算法C语言实现(二十七)--- 7.2图的遍历
一.简述 栈与队列,DFS与BFS.仅以连接表为例实现. 二.头文件 BFS要用到的头文件 //3_4_part1.h /** author:zhaoyu email:zhaoyu1995.com@g ...
- 数据结构算法C语言实现(二十)--- 6.3.1遍历二叉树
一.简述 二叉树的遍历主要是先序.中序.后序及对应的递归和非递归算法,共3x2=6种,其中后序非递归在实现上稍复杂一些.二叉树的遍历是理解和学习递归及体会栈的工作原理的绝佳工具! 此外,非递归所用的栈 ...
- 数据结构算法C语言实现(十二)--- 3.4循环队列&队列的顺序表示和实现
一.简述 空队列的处理方法:1.另设一个标志位以区别队列是空还是满:2.少用一个元素空间,约定以队列头指针在队尾指针下一位置上作为队列呈满的状态的标志. 二.头文件 //3_4_part1.h /** ...
- 数据结构算法C语言实现(十一)--- 3.4队列的链式表示和实现
一.简介 FIFO. 二.头文件 //3_4_part1.h /** author:zhaoyu email:zhaoyu1995.com@gmail.com date:2016-6-9 note:r ...
- 数据结构算法C语言实现(十)--- 3.3栈与递归的实现
一.简介 汉诺塔问题是递归的一个典型例子,而且书上的讲解很详细,对理解C语言函数及函数传参的工作机制很有帮助,值得一看.而且,递归在我看来和分治.DP.贪心等一样是十分优美的思想,值得学习!!! 二. ...
- 数据结构算法C语言实现(八)--- 3.2栈的应用举例:迷宫求解与表达式求值
一.简介 迷宫求解:类似图的DFS.具体的算法思路可以参考书上的50.51页,不过书上只说了粗略的算法,实现起来还是有很多细节需要注意.大多数只是给了个抽象的名字,甚至参数类型,返回值也没说的很清楚, ...
- 数据结构算法C语言实现(七)--- 3.1栈的线性实现及应用举例
一.简述 栈,LIFO.是操作受限的线性表,和线性表一样有两种存储表示方法.下面以顺序存储为例,实现. 二.ADT 暂无. 三.头文件 //3_1.h /** author:zhaoyu email: ...
- 数据结构算法C语言实现(六)---2.4一元多项式的表示及相加
一.简述 利用链表表示稀疏多项式,并基于之前的一些操作(编程实现上还是有所不同的)组合新的操作实现一元多项式的表示及相加. 二.ADT 抽象数据类型一元多项式的定义 ADT Polyomail{ 数据 ...
- 数据结构算法C语言实现(五)---2.3重新定义线性链表及其基本操作
一.简述 ...由于链表在空间的合理利用上和插入.删除时不需要移动等的优点,因此在很多场合下,它是线性表的首选存储结构.然而,它也存在着实现某些基本操作,如求线性表的长度时不如顺序存储结构的缺点:另一 ...
- 数据结构算法C语言实现(二)---2.3线性表的链式表示和实现之单链表
一.简述 [暂无] 二.头文件 #ifndef _2_3_part1_H_ #define _2_3_part1_H_ //2_3_part1.h /** author:zhaoyu email:zh ...
随机推荐
- SQL Server 大数据搬迁之文件组备份还原实战
一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 解决方案(Solution) 搬迁步骤(Procedure) 搬迁脚本(SQL Codes) ...
- 一起学微软Power BI系列-使用技巧(4)Power BI中国版企业环境搭建和帐号问题
千呼万唤的Power BI中国版终于落地了,相信12月初的微软技术大会之后已经铺天盖地的新闻出现了,不错,Power BI中国版真的来了,但还有些遗憾,国际版的一些重量级服务如power bi emb ...
- 使用 Nodejs 搭建简单的Web服务器
使用Nodejs搭建Web服务器是学习Node.js比较全面的入门教程,因为要完成一个简单的Web服务器,你需要学习Nodejs中几个比较重要的模块,比如:http协议模块.文件系统.url解析模块. ...
- TODO:Laravel 使用blade标签布局页面
TODO:Laravel 使用blade标签布局页面 本文主要介绍Laravel的标签使用,统一布局页面.主要用到到标签有@yield,@ stack,@extends,@section,@stop, ...
- 前端学Markdown
前面的话 我个人理解,Markdown就是一个富文本编辑器语言,类似于sass对于css的功能,Markdown也可以叫做HTML预处理器,只不过它是一门轻量级的标记语言,可以更简单的实现HTML ...
- 前端学HTTP之内容协商
前面的话 一个URL常常需要代表若干不同的资源.例如那种需要以多种语言提供其内容的网站站点.如果某个站点有说法语的和说英语的两种用户,它可能想用这两种语言提供网站站点信息.理想情况下,服务器应当向英语 ...
- [C#] C# 知识回顾 - 学会处理异常
学会处理异常 你可以使用 try 块来对你觉得可能会出现异常的代码进行分区. 其中,与之关联的 catch 块可用于处理任何异常情况. 一个包含代码的 finally 块,无论 try 块中是否在运行 ...
- Swift enum(枚举)使用范例
//: Playground - noun: a place where people can play import UIKit var str = "Hello, playground& ...
- Java 为值传递而不是引用传递
——reference Java is Pass by Value and Not Pass by Reference 其实这个问题是一个非常初级的问题,相关的概念初学者早已掌握,但是时间长了还是容易 ...
- .NET设计模式访问者模式
一.访问者模式的定义: 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 二.访问者模式的结构和角色: 1.Visitor 抽象访问者角色,为该 ...