二叉排序树的删除操作
时间:2022-04-22
本文章向大家介绍二叉排序树的删除操作,主要内容包括算法思想、函数代码:、全部代码:、运行示例:、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
算法思想
二叉排序树,删除操作主要针对三种情况。
1 叶子节点-直接删除就可以了
2 没有左孩子的节点-直接嫁接右子树就可以了(没有右孩子的节点-直接嫁接左子树就可以了)
3 如果左右子树都存在,则寻找删除节点的直接前驱(即左子树里面的最右的节点)
编程时需要注意,函数时针对指针的操作,因此为了修改指针,要使用二级指针传参才可以
例如:
void delete(BinaryTree **b){
....
}
int main(){
BinaryTree *b = (BinaryTree *)malloc(sizeof(BinaryTree));
delete(&b);
}
函数代码:
bool deleteTree(BTree **b,int key){
if(!*b)
return false;
else{
if((*b)->data == key){
return deleteNode(&(*b));
}
else if((*b)->data > key)
return deleteTree(&(*b)->lchild,key);
else
return deleteTree(&(*b)->rchild,key);
}
}
bool deleteNode(BTree **b){
BTree *p,*s;
if((*b)->lchild == NULL ){
p = (*b);
(*b) = (*b)->rchild;
free(p);
}else if((*b)->rchild == NULL){
p = (*b);
(*b) = (*b)->lchild;
free(p);
}else{
p = (*b);
s = (*b)->lchild;
while(s->rchild != NULL){
p = s;
s = s->rchild;
}
(*b)->data = s->data;
if(p != (*b))
p->rchild = s->lchild;
else
p->lchild = s->lchild;
free(s);
return true;
}
}
全部代码:
1 #include <stdio.h>
2 #include <stdlib.h>
3 typedef struct bTree{
4 int data;
5 struct bTree *lchild,*rchild;
6 }BTree;
7
8 void initialTree(BTree *b);
9 bool insertTree(BTree *b,int key);
10 int searchTree(BTree *b,int key,BTree *f,BTree *&p);
11 void InOrderTree(BTree *b);
12 bool deleteTree(BTree **b,int key);
13 bool deleteNode(BTree **b);
14
15 int main(){
16 BTree *b = (BTree *)malloc(sizeof(BTree));
17 b->data = 5;
18 b->lchild = b->rchild = NULL;
19 initialTree(b);
20 InOrderTree(b);
21 deleteTree(&b,4);
22 InOrderTree(b);
23 getchar();
24 return 0;
25 }
26 bool deleteTree(BTree **b,int key){
27 if(!*b)
28 return false;
29 else{
30 if((*b)->data == key){
31 return deleteNode(&(*b));
32 }
33 else if((*b)->data > key)
34 return deleteTree(&(*b)->lchild,key);
35 else
36 return deleteTree(&(*b)->rchild,key);
37 }
38 }
39 bool deleteNode(BTree **b){
40 BTree *p,*s;
41 if((*b)->lchild == NULL ){
42 p = (*b);
43 (*b) = (*b)->rchild;
44 free(p);
45 }else if((*b)->rchild == NULL){
46 p = (*b);
47 (*b) = (*b)->lchild;
48 free(p);
49 }else{
50 p = (*b);
51 s = (*b)->lchild;
52 while(s->rchild != NULL){
53 p = s;
54 s = s->rchild;
55 }
56 (*b)->data = s->data;
57 if(p != (*b))
58 p->rchild = s->lchild;
59 else
60 p->lchild = s->lchild;
61 free(s);
62 return true;
63 }
64 }
65 void InOrderTree(BTree *b){
66 if( !b )
67 return;
68 InOrderTree(b->lchild);
69 printf("%d ",b->data);
70 InOrderTree(b->rchild);
71 }
72
73 void initialTree(BTree *b){
74 insertTree(b,5);
75 insertTree(b,3);
76 insertTree(b,4);
77 insertTree(b,6);
78 insertTree(b,2);
79 insertTree(b,1);
80 insertTree(b,8);
81 }
82 int searchTree(BTree *b,int key,BTree *f,BTree *&p){
83 if(!b){
84 p = f;
85 printf("++%dn",p->data);
86 return 0;
87 }
88 else if( key == b->data){
89 p = b;
90 printf("--%d n",p->data);
91 printf("找到元素key:%dn",key);
92 return 1;
93 }
94 else if(key > b->data)
95 return searchTree(b->rchild,key,b,p);
96 else
97 return searchTree(b->lchild,key,b,p);
98 }
99 bool insertTree(BTree *b,int key){
100 BTree *p,*s;
101 if(!searchTree(b,key,NULL,p)){
102 printf("%d 没有出现在树中,可以插入在%d之后n",key,p->data);
103 s = (BTree *)malloc(sizeof(BTree));
104 s->data = key;
105 s->lchild = s->rchild = NULL;
106 if(!b){
107 b = s;
108 }
109 else if(key < p->data){
110 p->lchild = s;
111 }else{
112 p->rchild = s;
113 }
114 return true;
115 }else
116 return false;
117 }
运行示例:
- Go 语言的演化历程
- JS 评分五角星随鼠标移动显示
- Golang标准库学习——buffio包 ---转
- 【Go 语言社区】Go语言条件变量的两个例子
- mysqlimport导入报错的排查(r10笔记第58天)
- 【Go 语言社区】POJ 1047 Round and Round We Go 循环数新解
- 【Go 语言社区】删除redis所有KEY
- 【Go 语言社区】Golang 动态实例化结构体
- 【Go 语言社区】Go 错误处理
- 【Go 语言社区】Go 语言范围(Range)
- 【Go 语言社区】JS 相关---Window Location
- 【Go 语言社区】Go 语言Map(集合)
- 【Go 语言社区】JavaScript Date(日期)对象
- UWP基础教程 - XAML类型转换器
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 常用功能加载宏——单元格数字格式
- 【翻译】200行代码讲透RUST FUTURES (2)
- 【Rust日报】2020-07-23 Rust 的 CI 将使用 GitHub Actions
- 【每周一库】- Tonic 基于Rust的gRPC实现
- 错误捕获
- 常用功能加载宏——单元格合并
- 【Rust日报】2020-07-25 RustScan:一个Rust实现的更快的Nmap
- 常用功能加载宏——单元格字符处理
- 【翻译】Rust生命周期常见误区
- 代码管理
- 【翻译】200行代码讲透RUST FUTURES (3)
- ECCV2020 | FReLU:旷视提出一种新的激活函数,实现像素级空间信息建模
- 字符处理——大小写转换编码知识扩展
- 【Rust日报】2020-07-26 - Easy Rust 让Rust文档更容易理解
- VBA使用API_04:标准控件