【数据结构】——搜索二叉树的插入,查找和删除(递归&非递归)
一、搜索二叉树的插入,查找,删除
简单说说搜索二叉树概念:
二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树
若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
它的左右子树也分别为二叉搜索树
例如:int a [] = {5,3,4,1,7,8,2,6,0,9};
二叉树结构
typedef struct BSTreeNode
{
struct BSTreeNode *_left;
struct BSTreeNode *_right;
DataType _data;
}BSTreeNode;
二叉树节点创建
BSTreeNode *BuyTreeNode(DataType x) //创建节点
{
BSTreeNode *node = (BSTreeNode*)malloc(sizeof(BSTreeNode));
assert(node);
node->_data = x;
node->_left = NULL;
node->_right = NULL;
return node;
}
二叉搜索树操作:
1、搜索二叉树的插入:在二叉搜索树中插入新元素时,必须先检测该元素是否在树中已经存在。如果已经存在,则不进行插入;否则将新元素加入到搜索停止的地方。
非递归代码
int BSTreeNodeInsert(BSTreeNode **pptree,DataType x) //搜索树的插入
{
BSTreeNode *parent = NULL;
BSTreeNode *cur = *pptree;
if (*pptree == NULL)
{
*pptree = BuyTreeNode(x);
return 0;
}
while (cur)
{
parent = cur;
if (cur->_data > x)
cur = cur->_left;
else if (cur->_data < x)
cur = cur->_right;
else
return -1;
}
if (parent->_data > x)
parent->_left = BuyTreeNode(x);
else
parent->_right = BuyTreeNode(x);
return 0;
}
递归代码 :
int BSTreeNodeInsertR(BSTreeNode **tree,DataType x) //搜索树的插入
{
if(*tree == NULL)
{
*tree = BuyTreeNode(x);
return 0;
}
if ((*tree)->_data > x)
return BSTreeNodeInsertR(&(*tree)->_left,x);
else if ((*tree)->_data < x)
return BSTreeNodeInsertR(&(*tree)->_right,x);
else
return -1;
}
2、搜索二叉树的查找:
非递归代码
BSTreeNode *BSTreeNodeFind(BSTreeNode *tree,DataType x) //查找
{
while (tree)
{
if (tree->_data == x)
return tree;
else if (tree->_data < x)
tree = tree->_right;
else
tree = tree->_left;
}
return NULL;
}
递归代码
BSTreeNode *BSTreeNodeFindR(BSTreeNode *tree,DataType x) //查找
{
if (!tree)
return NULL;
if (tree->_data > x)
BSTreeNodeFindR(tree->_left,x);
else if (tree->_data < x)
BSTreeNodeFindR(tree->_right,x);
else
return tree;
}
3、搜索二叉树的删除:
首先查找元素是否在二叉搜索树中,如果不存在,则返回, 否则要删除的结点可能分下面四种情况:
a. 要删除的结点无孩子结点
b. 要删除的结点只有左孩子结点
c. 要删除的结点只有右孩子结点
d. 要删除的结点有左、右孩子结点
情况1可以归类到2或者3
对于上述情况,相应的删除方法如下:
a. 直接删除该结点
b. 删除该结点且使被删除节点的双亲结点指向被删除节点的左孩子结点
c. 删除该结点且使被删除节点的双亲结点指向被删除结点的右孩子结点
d. 在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被删除节点中,在来处理该结点的删除问题
代码实现:
int BSTreeNodeDel(BSTreeNode **tree,DataType x) //删除
{
BSTreeNode *cur = *tree;
BSTreeNode *parent = *tree;
BSTreeNode *del = NULL;
while (cur)
{
if (cur->_data > x)
{
parent = cur;
cur = cur->_left;
}
else if (cur->_data < x)
{
parent = cur;
cur = cur->_right;
}
else
{
del = cur;
if (cur->_left == NULL) //1、左孩子为空
{
if (parent->_left == cur)
parent->_left = cur->_right;
else if (parent->_right == cur)
parent->_right = cur->_right;
else if (parent == cur) //没有父亲节点时
*tree = parent->_right;
}
else if (cur->_right == NULL) //2、右孩子为空
{
if (parent->_left == cur)
parent->_left = cur->_left;
else if (parent->_right == cur)
parent->_right = cur->_left;
else if (parent == cur) //没有父亲节点时
*tree = parent->_left;
}
else//3、左右孩子都不为空
{
BSTreeNode *sub = cur->_right;
while (sub->_left)
{
parent = sub;
sub = sub->_left;
}
del = sub;
cur->_data = sub->_data;
if (parent->_left == sub)
parent->_left = sub->_right;
else
parent->_right = sub->_right;
}
free(del);
del = NULL;
return 0;
}
}
return -1;
}
完整代码请私信或者点此链接下载【数据结构】——搜索二叉树的插入,查找和删除(递归&非递归)
【数据结构】——搜索二叉树的插入,查找和删除(递归&非递归)的更多相关文章
- 二叉树——遍历篇(递归/非递归,C++)
二叉树--遍历篇 二叉树很多算法题都与其遍历相关,笔者经过大量学习.思考,整理总结写下二叉树的遍历篇,涵盖递归和非递归实现. 1.二叉树数据结构及访问函数 #include <stdio.h&g ...
- 二叉树的递归,非递归遍历(C++)
二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的.对于二叉树,有前序.中序以及后序三种遍历方法.因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易 ...
- 二叉树的先序、中序以及后序遍历(递归 && 非递归)
树节点定义: class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } 递归建立二 ...
- 递归/非递归----python深度遍历二叉树(前序遍历,中序遍历,后序遍历)
递归代码:递归实现很简单 '二叉树结点类' class TreeNode: def __init__(self, x): self.val = x self.left = None self.righ ...
- Java实现二叉树的创建、递归/非递归遍历
近期复习数据结构中的二叉树的相关问题,在这里整理一下 这里包含: 1.二叉树的先序创建 2.二叉树的递归先序遍历 3.二叉树的非递归先序遍历 4.二叉树的递归中序遍历 5.二叉树的非递归中序遍历 6. ...
- C++二叉树前中后序遍历(递归&非递归)统一代码格式
统一下二叉树的代码格式,递归和非递归都统一格式,方便记忆管理. 三种递归格式: 前序遍历: void PreOrder(TreeNode* root, vector<int>&pa ...
- 二叉树总结—建树和4种遍历方式(递归&&非递归)
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u013497151/article/details/27967155 今天总结一下二叉树.要考离散了 ...
- [javaSE] 数据结构(二叉树-遍历与查找)
前序遍历:中,左,右 中序遍历:左,中,右 后序遍历:左,右,中 二叉树查找 从根节点进行比较,目标比根节点小,指针移动到左边 从根节点进行比较,目标比根节点大,指针移动到右边 /** * 前序遍历 ...
- c++实现二叉树层序、前序创建二叉树,递归非递归实现二叉树遍历
#include <iostream> #include <cstdio> #include <stdio.h> #include <string> # ...
随机推荐
- ThinkPHP5上传图片并压缩为缩略图
使用thinkphp开发app后端中,需要实现一个处理上传图片队列的功能 这是个上传多图片保存并且需要对其中一张图片进行压缩的功能 (使用的html5 mui框架开发app,如果直接载入原图,app客 ...
- CCF系列之日期计算(201509-2)
试题编号: 201509-2 时间限制: 1.0s 内存限制: 256.0MB 问题描述 给定一个年份y和一个整数d,问这一年的第d天是几月几日? 注意闰年的2月有29天.满足下面条件之一的是闰年: ...
- python 操作python
#!/usr/bin/env python#_*_ coding:utf-8 _*_ import MySQLdb # 打开门conn = MySQLdb.connect(host='192.168. ...
- mysql视图定义、原理、创建、使用
定义: 视图是一个虚拟表,其内容由查询定义.同真实的表一样,视图包含一系列带有名称的列和行数据.但是视图并不在数据库中以存储的数据值集形式存在.行和列数据来自由定义视图的查询所引用的表,并在引用视图时 ...
- windows7 设定开关机事件
动记录开关机的技能你知道吗? 下面跟我来设定一下记录电脑的开关机时间吧,工作常常会用到的. 在""我的电脑"右击=>管理=>系统工具=>时间查看器=&g ...
- js随机生成验证码及其颜色
今天迎来了2018年第一场雪,这个美好的日子,总的写点什么纪念一下,在这里写了一个在js中使用Math.random()函数,随机生成四位数的验证码及其验证码换颜色. js代码如下: var arra ...
- linkin大话设计模式--代理模式
代理模式是一种应用非常广泛的设计模式,当客户端代码需要调用某个对象的时候,客户端并不关心是否可以准确的得到这个对象,他只要一个能够提供该功能的对象而已,此时我们就可以返回该对象的代理.总而言之,客户端 ...
- awk -f program.file 功能使用
一.awk -f program.file 功能使用 一直没有使用过awk的-f功能,感觉鸡肋,不是很实用,更多的是因为没有需求的原因 下面介绍下awk -f的使用方法 awk可以指定默认的文件路径, ...
- 【转】C++易混知识点3. New Operator, Operator New, Placement New 实例分析,比较区别
我们知道,C++中引入了New 这个内置符号,很大方便了指针的使用,程序员不必关注与这块堆上新分配的内存是如何来的,如何初始化的,然后如何转换为我们想要的类型指针的.现在,我们重点来分析下这个NEW内 ...
- iOS导出ipa包时四个选项的意义
1. Save for iOS App Store Deployment 保存到本地 准备上传App Store 或者在越狱的iOS设备上使用 2. Save for Ad Hoc Deploymen ...