值得一说的是删除操作,删除操作我们分为三种情况:

1.要删的节点有两个孩子:

  找到左子树中的最大值或者右子树中的最小值所对应的节点,记为node,并把node的值赋给要删除的节点del,然后删除node

实际上真正删除的是node,del只是发生了一次值的替换。

为了方便理解和操作,我们把两个孩子的情况放在最前面,这样经过以上处理后,该节点就会变成情况2或者情况3 ,接下爱这行这两种情况的代码。

2.要删的节点有一个孩子

r判断要删除的节点del是其父亲father的左孩子还是右孩子,以是father的左孩子为例,del是father的左孩子,接下来判断del是否有左孩子,

如果有,则father的左孩子变成del的左孩子,如果没有,则father的左孩子变成del的右孩子。

3.要删的节点没有孩子

即为当情况2 del的左孩子右孩子为空的时候

#include<stdio.h>
#include<stdlib.h>
typedef struct Tree
{
int data;
Tree*right;
Tree*left;
}BinaryTree;
void insert(BinaryTree **p,int e)
{
BinaryTree *temp=(BinaryTree*)malloc(sizeof(BinaryTree));
temp->data=e;
temp->left=NULL;
temp->right=NULL; if(*p==NULL)
{
*p=temp;
return ;
}
BinaryTree*root=*p;
while(1)
{
if(e<root->data)
{
if(root->left)
{
root=root->left;
}
else
{
root->left=temp;
break;//完成插入操作了
} }
else if(e>root->data)
{
if(root->right)
{
root=root->right; }
else
{
root->right=temp;
break;
}
}
}
}
void FindNode(BinaryTree* p,BinaryTree **del,BinaryTree**father, int e)//我们在删除操作中不仅需要知道要删除哪个节点,还要知道要删除节点的父亲
{                                          //return无法返回两个值,要实现返回两个值,我们在这里采用二级指针
while(1) //实际上也可以通过结构体封装来完成同时返回两个值
{
if(e<p->data)
{
*father=p;//每次都记录一下父亲
p=p->left;
}
else if(e>p->data)
{
*father=p;
p=p->right;
}
else if(e==p->data)
{
*del=p;return ;
}
}
}
void deleteNode(BinaryTree **p,int e)//
{
if(*p==NULL) return ;
BinaryTree *root=*p;
BinaryTree *del=NULL;
BinaryTree *father=NULL;
BinaryTree *pmark=NULL;
FindNode(root,&del,&father,e);
if(del->left&&del->right)
{
pmark=del;//标记要删除的点
father=del;
del=del->left;
while(del->right)
{
father=del;
del=del->right;
}
pmark->data=del->data;
}
//接下来分析有一个或者没有孩子的情况
//被删节点 是根
if(father==NULL)//??
{
*p=del->left?del->left:del->right;
free(del);
return ;
}
else
{//不用在写判断条件了,走到这说明就是一个或者没有孩子,只需要判断是哪边的孩子就可
if(del==father->left)
father->left=del->left?del->left:del->right;
else if(del==father->right)
father->right=del->left?del->left:del->right;
free(del); }
}
void inorder(BinaryTree *p)
{
if(p==NULL) return ;
//递归要有结束条件
inorder(p->left);
printf(" %d ",p->data);
inorder(p->right);
}
void preorder(BinaryTree *p)
{
if(p==NULL) return ;
//递归要有结束条件 printf(" %d ",p->data);
preorder(p->left);
preorder(p->right);
}
int main()
{
int m;
BinaryTree *p=NULL;
int a[10];
int i;
scanf("%d",&m);
for(i=0;i<m;i++)
{
scanf("%d",&a[i]);
}
for(i=0;i<m;i++)
{
insert(&p,a[i]);
}
preorder(p);
printf("\n");
inorder(p);
deleteNode(&p,9);
preorder(p);
printf("\n");
inorder(p);
return 0;
}

  

BST(二叉排序树)的插入与删除的更多相关文章

  1. 二叉搜索树(BST)的插入和删除递归实现

    思路 二叉搜索树的插入 TreeNode InsertRec(rootNode, key) = if rootNode == NULL, return new Node(key) if key > ...

  2. 数据结构学习-BST二叉查找树 : 插入、删除、中序遍历、前序遍历、后序遍历、广度遍历、绘图

    二叉查找树(Binary Search Tree) 是一种树形的存储数据的结构 如图所示,它具有的特点是: 1.具有一个根节点 2.每个节点可能有0.1.2个分支 3.对于某个节点,他的左分支小于自身 ...

  3. Java实现二叉排序树的插入、查找、删除

    import java.util.Random; /** * 二叉排序树(又称二叉查找树) * (1)能够是一颗空树 * (2)若左子树不空,则左子树上全部的结点的值均小于她的根节点的值 * (3)若 ...

  4. 算法与数据结构(十) 二叉排序树的查找、插入与删除(Swift版)

    在上一篇博客中,我们主要介绍了四种查找的方法,包括顺序查找.折半查找.插入查找以及Fibonacci查找.上面这几种查找方式都是基于线性表的查找方式,今天博客中我们来介绍一下基于二叉树结构的查找,也就 ...

  5. 详细教你实现BST(二叉排序树)

    查找基本分类如下: 线性表的查找 顺序查找 折半查找 分块查找 树表的查找 二叉排序树 平衡二叉树 B树 B+树 散列表的查找 今天介绍二叉排序树. 二叉排序树 ( Binary Sort Tree ...

  6. 二叉查找树(查找、插入、删除)——C语言

    二叉查找树 二叉查找树(BST:Binary Search Tree)是一种特殊的二叉树,它改善了二叉树节点查找的效率.二叉查找树有以下性质: (1)若左子树不空,则左子树上所有节点的值均小于它的根节 ...

  7. 二叉查找树的查找、插入和删除 - Java实现

    http://www.cnblogs.com/yangecnu/p/Introduce-Binary-Search-Tree.html 作者: yangecnu(yangecnu's Blog on ...

  8. 【算法】【python实现】二叉搜索树插入、删除、查找

    二叉搜索树 定义:如果一颗二叉树的每个节点对应一个关键码值,且关键码值的组织是有顺序的,例如左子节点值小于父节点值,父节点值小于右子节点值,则这棵二叉树是一棵二叉搜索树. 类(TreeNode):定义 ...

  9. AVL树的插入和删除

    一.AVL 树 在计算机科学中,AVL树是最早被发明的自平衡二叉查找树.在AVL树中,任一节点对应的两棵子树的最大高度差为 1,因此它也被称为高度平衡树.查找.插入和删除在平均和最坏情况下的时间复杂度 ...

  10. 我的MYSQL学习心得(八) 插入 更新 删除

    我的MYSQL学习心得(八) 插入 更新 删除 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得( ...

随机推荐

  1. 怎么归档老日志的shell脚本

    本脚本来自有学习阿铭的博文学习:工作中,需要用到日志切割logrotate,按照各自的需要切割.定义保留日志.提示:本文中的S全部都$符,不要问为什么,马云爸爸的社区就这样. #用途:日志切割归档.按 ...

  2. 干货:Java并发编程系列之volatile(二)

    接上一篇<Java并发编程系列之synchronized(一)>,这是第二篇,说的是关于并发编程的volatile元素. Java语言规范第三版中对volatile的定义如下:Java编程 ...

  3. trace

    linux 下程序的系统调用和信号调用跟踪工具 http://www.cnblogs.com/qingquan/archive/2011/07/18/2110072.html

  4. Hive-复制表

    非分区表复制 复制一张非分区表,使用CREATE TABLE IF NOT EXISTS AS SELECT * FROM tb_name;只复制表结构,CREATE TABLE IF NOT EXI ...

  5. 20165211 学习基础和C语言调查

    20165211 学习基础和C语言调查 理论脱离实践是最大的不幸.--达芬奇 达芬奇,是我眼里最有嫌疑的穿越者. 绘画.天文.雕塑.音乐.发明.建筑,数学.生理.物理.天文.地质--我很难想象有一个人 ...

  6. hdu Naive Operations 线段树

    题目大意 题目链接Naive Operations 题目大意: 区间加1(在a数组中) 区间求ai/bi的和 ai初值全部为0,bi给出,且为n的排列,多组数据(<=5),n,q<=1e5 ...

  7. 获取转UTF8的字符串

    /// <summary> /// 获取转UTF8的字符串 /// </summary> /// <param name="strWord">& ...

  8. 51nod 1080 两个数的平方和

    没心情写数学题啦啊   好难啊 #include<bits/stdc++.h> using namespace std; set<int> s; set<int>: ...

  9. zepto点透解决思路

    首先看几个链接, http://blog.youyo.name/archives/zepto-tap-click-through-research.html youyo的分析 http://softw ...

  10. Mui --- 弹出菜单

    mui框架内置了弹出菜单插件,弹出菜单显示内容不限,但必须包裹在一个含.mui-popover类的div中,如下即为一个弹出菜单内容: <div id="popover" c ...