我们将查找分类可以分为如下几类:
这节我们重点讲二叉搜索树,在讲之前我们先明白几个知识点:
搜索:在数据元素集合中查找是否存在关键字等于某个给定关键字数据元素的过程
搜索的结果:搜索成功、搜索失败
用于搜索的数据集合称为搜索结构,由统一数据类型的元素组成,根据集合中数据的组织结构选择合适的搜索方法。
二叉搜索树(二叉排序树):
它或者是一棵空数或者具有如下的性质:
- 若它的左子树不为空,那么左子树上所有节点的值都小于根节点
- 若它的右子树不为空,那么右子树上所有节点的值都大于根节点
- 它的左右子树也都为二叉搜索树
下面我们实现堆二叉搜索树的基本操作:初始化、插入、删除、查找
需要特别说明:
在实现插入时需要考虑以下两点:
1.如果这个树是空树
2.如果这个树不是空树:a)先查找到一个合适的插入位置 b)再在对应的位置上创建节点
在实现删除时需要考虑以下四点:
1.处理空树的情况,直接返回
2.找到要删除的节点的位置,以及要删除节点的父节点
3.如果要查找元素在树中没有找到,直接返回
4.如果要删除的节点存在,要分情况讨论:
a) 要删除的节点,没有子树,直接删除该节点,并且将父节点置空
b)要删除节点,只有左子树,删除该节点的同时将改节点的左子树挂在父节点上
c)要删除节点,只有右子树,删除该节点同时将该节点的右子树挂在父节点上
d)要删除节点,同时有左右子树,找到右子树中的最小值,然后将改最小值与赋值给要删除的位置,然后再删除改右子树中的最小值节点,这样一个节点最多只有一个右子树,就转换成了情况c)
具体实现代码如下:
search_tree.c
1 #include"search_tree.h"
2 #include<stdio.h>
3 #include<stdlib.h>
4 void SearchTreeInit(SearchTreeNode**root)
5 {
6 if(root==NULL)
7 {
8 return ;
9 }
10 *root=NULL;
11 return;
12 }
13 SearchTreeNode* CreateNode(SearchTreeType key)
14 {
15 SearchTreeNode*new_node=(SearchTreeNode*)malloc(sizeof(SearchTreeNode));
16 new_node->key=key;
17 new_node->lchild=NULL;
18 new_node->rchild=NULL;
19 return new_node;
20 }
21 void SearchTreeInsert(SearchTreeNode**root,SearchTreeType key)
22 {
23 if(root==NULL)
24 {
25 return;
26 }
27 if(*root==NULL)
28 {
29 *root=CreateNode(key);
30 }
31 SearchTreeNode *cur=*root;
32 SearchTreeNode*parent=NULL;
33 while(1)
34 {
35 if(cur==NULL)
36 {
37 break;
38 }
39 if(key<cur->key)
40 {
41 parent=cur;
42 cur=cur->lchild;
43 }
44 else if(key>cur->key)
45 {
46 parent=cur;
47 cur=cur->rchild;
48 }
49 else
50 {
51 return;
52 }
53 }
54 SearchTreeNode*new_node=CreateNode(key);
55 if(key<parent->key)
56 {
57 parent->lchild=new_node;
58 }
59 else
60 {
61 parent->rchild=new_node;
62 }
63 return;
64 }
65 SearchTreeNode* SearchTreeFind(SearchTreeNode*root,SearchTreeType to_find)
66 {
67 if(root==NULL)
68 {
69 return;
70 }
71 SearchTreeNode*cur=root;
72 while(1)
73 {
74 if(cur==NULL)
75 {
76 break;
77 }
78 if(to_find<cur->key)
79 {
80 cur=cur->lchild;
81 }
82 if(to_find>cur->key)
83 {
84 cur=cur->rchild;
85 }
86 else
87 break;
88 }
89 return cur;
90 }
91 void SearchTreeRemove(SearchTreeNode**root,SearchTreeType key)
92 {
93 if(root==NULL)
94 {
95 return;
96 }
97 if(*root==NULL)
98 {
99 return;
100 }
101 SearchTreeNode*pos=*root;
102 SearchTreeNode*parent=NULL;
103 while(pos!=NULL)
104 {
105 if(key<pos->key)
106 {
107 parent=pos;
108 pos=pos->lchild;
109 }
110 else if(key>pos->key)
111 {
112 parent=pos;
113 pos=pos->rchild;
114 }
115 else
116 {
117 break;
118 }
119 }
120 if(pos==NULL)
121 {
122 return;
123 }
124 if(pos->lchild==NULL&&pos->rchild==NULL)
125 {
126 if(pos==*root)
127 {
128 *root=NULL;
129 }
130 else
131 {
132 if(parent->lchild==pos)
133 {
134 parent->lchild=NULL;
135 }
136 if(parent->rchild==pos)
137 {
138 parent->rchild=NULL;
139 }
140 }
141 free(pos);
142 return;
143 }
144 else if(pos->lchild!=NULL&&pos->rchild==NULL)
145 {
146 if(pos==*root)
147 {
148 *root=pos->lchild;
149 }
150 else
151 {
152 if(pos==parent->lchild)
153 {
154 parent->lchild=pos->lchild;
155 }
156 else
157 {
158 parent->rchild=pos->lchild;
159 }
160 }
161 free(pos);
162 return;
163 }
164 else if(pos->lchild==NULL&&pos->rchild!=NULL)
165 {
166 if(pos==*root)
167 {
168 *root=pos->rchild;
169 }
170 else
171 {
172 if(pos==parent->lchild)
173 {
174 parent->lchild=pos->rchild;
175 }
176 else
177 {
178 parent->rchild=pos->rchild;
179 }
180 }
181 free(pos);
182 return;
183 }
184 else
185 {
186 SearchTreeNode*min=pos->rchild;
187 SearchTreeNode*min_parent=pos;
188 while(min->lchild!=NULL)
189 {
190 min_parent=min;
191 min=min->lchild;
192 }
193 pos->key=min->key;
194 if(min_parent->lchild==min)
195 {
196 min_parent->lchild=min->rchild;
197 }
198 else
199 {
200 min_parent->rchild=min->rchild;
201 }
202 free(min);
203 return;
204 }
205
206 }
207 ///以下为测试代码
208 void PreOrder(SearchTreeNode*root)
209 {
210 if(root==NULL)
211 {
212 return;
213 }
214 printf("%c",root->key);
215 PreOrder(root->lchild);
216 PreOrder(root->rchild);
217 return;
218 }
219 void InOrder(SearchTreeNode*root)
220 {
221 if(root==NULL)
222 {
223 return;
224 }
225 InOrder(root->lchild);
226 printf("%c",root->key);
227 InOrder(root->rchild);
228 return;
229 }
230 void TestInit()
231 {
232 SearchTreeNode *root;
233 SearchTreeInit(&root);
234 printf("root expected is NULL,actual is %p",root);
235 }
236 void TestInsert()
237 {
238 SearchTreeNode*root;
239 SearchTreeInit(&root);
240 SearchTreeInsert(&root,'a');
241 SearchTreeInsert(&root,'b');
242 SearchTreeInsert(&root,'c');
243 SearchTreeInsert(&root,'d');
244 SearchTreeInsert(&root,'e');
245 SearchTreeInsert(&root,'f');
246 SearchTreeInsert(&root,'g');
247 printf(" xian xu ");
248 PreOrder(root);
249 printf("\n");
250 printf(" zhong xu ");
251 InOrder(root);
252 }
253 void TestFind()
254 {
255 SearchTreeNode *root;
256 SearchTreeInit(&root);
257 SearchTreeInsert(&root,'b');
258 SearchTreeInsert(&root,'a');
259 SearchTreeInsert(&root,'g');
260 SearchTreeInsert(&root,'d');
261 SearchTreeInsert(&root,'e');
262 SearchTreeInsert(&root,'f');
263 SearchTreeNode*result=SearchTreeFind(root,'e');
264 printf("result expected %p,actual %p",root->rchild->lchild->rchild,result);
265 }
266 void TestRemove()
267 {
268 SearchTreeNode*root;
269 SearchTreeInit(&root);
270 SearchTreeInsert(&root,'b');
271 SearchTreeInsert(&root,'a');
272 SearchTreeInsert(&root,'g');
273 SearchTreeInsert(&root,'d');
274 SearchTreeInsert(&root,'e');
275 SearchTreeInsert(&root,'f');
276 SearchTreeRemove(&root,'a');
277 printf(" xian xu ");
278 PreOrder(root);
279 printf(" zhong xu");
280 InOrder(root);
281
282 }
283 int main()
284 {
285 TestInit();
286 printf("\n");
287 TestInsert();
288 printf("\n");
289 TestFind();
290 printf("\n");
291 TestRemove();
292 return 0;
293 }
search_tree.h
1 #pragma once
2 typedef char SearchTreeType;
3 typedef struct SearchTreeNode{
4 SearchTreeType key;
5 struct SearchTreeNode *lchild;
6 struct SearchTreeNode *rchild;
7 }SearchTreeNode;
8
9 void SearchTreeInit(SearchTreeNode **root);
10 void SearchTreeInsety(SearchTreeNode**root,SearchTreeType key);
11 SearchTreeNode* SearchTreeFind(SearchTreeNode* root,SearchTreeType to_find);
12 void SearchTreeRemove(SearchTreeNode** root,SearchTreeType to_remove);