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

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. Python Web笔记之高性能网络编程

    请参考博客: https://blog.csdn.net/russell_tao/article/details/9111769

  2. Js/html格式化在线工具

    Js/html格式化在线工具 Js/html格式化在线工具:http://tool.chinaz.com/Tools/jsformat.aspx

  3. Python网络爬虫案例(二)——爬取招聘信息网站

    利用Python,爬取 51job 上面有关于 IT行业 的招聘信息 版权声明:未经博主授权,内容严禁分享转载 案例代码: # __author : "J" # date : 20 ...

  4. 20145315《网络对抗》——注入shellcode以及 Return-to-libc攻击实验

    shellcode 准备一段Shellcode 我用的老师的shellcode:\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3 ...

  5. C++写入mbr

    #include <windows.h> #include <winioctl.h> unsigned char scode[] = "\xb8\x12\x00\xc ...

  6. grep如何结尾匹配

    答:grep "jello$" 如:git branch输出以下内容: yes-jello-good yes-jellos yes-jello 那么使用以下命令只能过滤出一行: $ ...

  7. 地宫取宝|2014年蓝桥杯B组题解析第九题-fishers

    地宫取宝 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标签. 地宫的入口在左上角,出口在右下角. 小明被带到地宫的入口,国王要求他只能向右或向下行走. 走 ...

  8. 关于 Local feature 和 Global feature 的组合

     关于  Local feature 和 Global feature 的组合     1.全局上下文建模:  

  9. java进制转换代码

    定义十进制的数直接写,定义8进制的数以0开头,定义二进制的数以0b开头,定义十六进制的数以0x开头需要将十进制的数以二进制的数表示出来可以参照下例: int a = 10; System.out.pr ...

  10. 用jQuery实现ajax总结以及跨域问题

    本文为作者原创,未经博主允许,不可转载 ajax请求的常用的参数设置: type:请求类型,"POST","GET",默认为geturl:发送请求的地址data ...