2.5. 二叉搜索树和平衡二叉树
本文参考:
2.5.1. 二叉搜索树
二叉搜索树(BST,binary search tree) 也称二叉查找树。满足一下性质。
非空左子树的所有键值小于其根节点的键值。
非空柚子树的所有键值大于其根节点的键值。
左右子树都是二叉搜索树。
抽象数据结构描述
类型名称: 二叉搜索树
数据对象集: 一个有穷的节点集合
操作集:
Position Find(ElementType item , BinTree bst): 从二叉树查找元素,返回节点地址。
Position FinMin(BinTree bst): 查找并返回最小值所在节点地址。
Position FinMax(BinTree bst): 查找并返回最大值所在节点地址。
BinTree Insert(ElementType item , BinTree bst): 插入元素。
BinTree Delete(ElementType item , BinTree bst): 删除元素。
2.5.2. 二叉搜索树实现
1// bitree_link_base.h
2#pragma once
3#include <stdio.h>
4#include <stdlib.h>
5
6#define ElementType int
7typedef struct TreeNode *BsTree ;
8typedef BsTree Position ;
9struct TreeNode{
10 ElementType Data ;
11 BsTree Left;
12 BsTree Right;
13};
1// bstree_link_base.c
2#include <stdio.h>
3#include <stdlib.h>
4#include "bitree_link_base.h"
5
6
7// 判断树是否为空
8int TreeIsEmpty(BsTree bt) {
9 if (bt == NULL) {
10 return 1;
11 }
12 return 0;
13}
14
15// 创建树
16BsTree CreateBsTree() {
17 BsTree bt = (BsTree) malloc(sizeof(struct TreeNode));
18 return bt;
19}
20
21Position FindByRecursive(ElementType item, BsTree bst) {
22 if (!bst) {
23 return NULL;
24 }
25 if (item == bst->Data) {
26 return bst;
27 }
28 if (item > bst->Data) {
29 return FindByRecursive(item, bst->Right);
30 }
31 if (item < bst->Data) {
32 return FindByRecursive(item, bst->Left);
33 }
34}
35
36Position FindByIterate(ElementType item, BsTree bst) {
37
38 BsTree pst = bst;
39 while (pst) {
40 if (pst->Data == item) {
41 return pst;
42 }
43 if (item > pst->Data) {
44 pst = pst->Right;
45 } else {
46 pst = pst->Left;
47 }
48 }
49 return NULL;
50}
51
52Position FindMax(BsTree bst) {
53 BsTree pst = bst;
54 while (pst && pst->Right) {
55 pst = pst->Right;
56 }
57 return pst;
58
59}
60
61Position FindMin(BsTree bst) {
62 BsTree pst = bst;
63 while (pst && pst->Left) {
64 pst = pst->Left;
65 }
66 return pst;
67
68}
69
70// 前序递归
71void PreOrderTraversalByRecursive(BsTree bt) {
72 if (bt) {
73 printf("%d ", bt->Data);
74 PreOrderTraversalByRecursive(bt->Left);
75 PreOrderTraversalByRecursive(bt->Right);
76 }
77}
78
79BsTree InsertByIterate(ElementType item, BsTree bst) {
80 // BsTree pst = bst ;
81 BsTree parent = bst;
82 BsTree current = bst;
83 while (current) {
84 parent = current ;
85 if (item > current->Data) {
86 current = current->Right;
87
88 } else {
89 current = current->Left;
90 }
91 }
92
93 BsTree node = malloc(sizeof(struct TreeNode));
94 node->Data = item;
95 node->Left = NULL;
96 node->Right = NULL;
97 if (item > parent->Data) {
98 parent->Right = node;
99 } else {
100 parent->Left = node;
101 }
102
103 return bst;
104
105}
106
107BsTree InsertByRecursive(ElementType item, BsTree bst) {
108 if ( ! bst ){
109 BsTree node = malloc(sizeof(struct TreeNode));
110 node->Data = item;
111 node->Left = node->Right = NULL;
112 return node;
113 }
114 if (item > bst->Data ){
115 bst->Right = InsertByRecursive(item,bst->Right);
116 }else{
117 bst->Left = InsertByRecursive(item,bst->Left);
118 }
119 return bst ;
120 // == 这个咱不考虑
121}
122
123BsTree DeleteByRecursive(ElementType item, BsTree bst) {
124 if ( !bst ){
125 printf("找不到删除元素");
126 return NULL;
127 }
128 if (item > bst->Data ){
129 bst->Right = DeleteByRecursive(item,bst->Right);
130 }else if(item < bst->Data ){
131 bst->Left = DeleteByRecursive(item,bst->Left);
132 }else{
133 // 左节点为空的删除
134 if (!bst->Left ){
135 bst = bst->Right;
136 }else if (!bst->Right){ // 右节点为空。
137 bst = bst->Left ;
138 }else{
139 // 左右都有的。
140 Position tmp = FindMin(bst->Right);
141 bst->Data = tmp->Data;
142 bst->Right = DeleteByRecursive(bst->Data,bst->Right);
143 }
144 }
145 return bst ;
146}
147
148BsTree CreateDemoTree() {
149 /*
150 40
151 20 60
152 10 30 50
153
154
155 * */
156 BsTree bt1 = CreateBsTree();
157 bt1->Data = 40;
158 BsTree bt2 = CreateBsTree();
159 bt2->Data = 20;
160 BsTree bt3 = CreateBsTree();
161 bt3->Data = 60;
162 BsTree bt4 = CreateBsTree();
163 bt4->Data = 10;
164 BsTree bt5 = CreateBsTree();
165 bt5->Data = 30;
166 BsTree bt6 = CreateBsTree();
167 bt6->Data = 50;
168
169 bt1->Left = bt2;
170 bt1->Right = bt3;
171
172 bt2->Left = bt4;
173 bt2->Right = bt5;
174
175 bt3->Left = bt6;
176 return bt1;
177}
178
179int mainByIterate() {
180 Position pos;
181 BsTree bst = CreateDemoTree();
182 printf("PreOrderTraversal\n");
183 PreOrderTraversalByRecursive(bst);
184 printf("\n");
185
186 pos = FindByIterate(20, bst);
187 PreOrderTraversalByRecursive(pos);
188 printf("\n");
189
190 pos = FindMax(bst);
191 PreOrderTraversalByRecursive(pos);
192 printf("\n");
193
194 pos = FindMin(bst);
195 PreOrderTraversalByRecursive(pos);
196 printf("\n");
197
198
199// bst = InsertByIterate(33, bst);
200// PreOrderTraversalByRecursive(bst);
201// printf("\n");
202
203// bst = DeleteByRecursive(70, bst);
204// PreOrderTraversalByRecursive(bst);
205// printf("\n");
206// bst = DeleteByRecursive(80, bst);
207// PreOrderTraversalByRecursive(bst);
208// printf("\n");
209
210 bst = DeleteByRecursive(20, bst);
211 PreOrderTraversalByRecursive(bst);
212 printf("\n");
213}
214int mainByRecursive() {
215 Position pos;
216 BsTree bst = CreateDemoTree();
217 printf("PreOrderTraversal\n");
218 PreOrderTraversalByRecursive(bst);
219 printf("\n");
220
221 pos = FindByRecursive(20, bst);
222 PreOrderTraversalByRecursive(pos);
223 printf("\n");
224
225
226
227 pos = FindMax(bst);
228 PreOrderTraversalByRecursive(pos);
229 printf("\n");
230
231 pos = FindMin(bst);
232 PreOrderTraversalByRecursive(pos);
233 printf("\n");
234
235 bst = InsertByRecursive(70, bst);
236 PreOrderTraversalByRecursive(bst);
237 printf("\n");
238
239
240
241 bst = DeleteByRecursive(40, bst);
242 PreOrderTraversalByRecursive(bst);
243 printf("\n");
244
245
246
247}
248
249int main(){
250 mainByRecursive();
251 // mainByIterate()
252}
2.5.3. 平衡二叉树(AVL)
平衡因子绝对值小于等于1的搜索树才是平衡二叉树。
平衡因子= 左树高度-右树高度。
2.5.4. 平衡二叉树实现
1#include <stdio.h>
2#include <stdlib.h>
3
4#define ElementType int
5typedef struct AVLNode *AVLTree;
6struct AVLNode {
7 ElementType Data;
8 AVLTree Left;
9 AVLTree Right;
10 int Height;
11};
12
13AVLTree CreateAvlTree(){
14 AVLTree t = (AVLTree)malloc(sizeof(struct AVLNode));
15 return t ;
16}
17
18int Max(int a, int b) {
19 if (a > b) {
20 return a;
21 }
22 return b;
23}
24
25int GetHeight(AVLTree t) ;
26void UpdateHeight(AVLTree t) {
27 t->Height = Max(GetHeight(t->Left), GetHeight(t->Right)) + 1;
28 return ;
29}
30
31
32int GetHeight(AVLTree t) {
33 int rightHeight;
34 int leftHeight;
35 if (!t) {
36 return 0;
37 }
38 UpdateHeight(t);
39 return t->Height;
40}
41
42AVLTree RR(AVLTree a) {
43 AVLTree b = a->Right;
44 a->Right = b->Left;
45 b->Left = a;
46
47 UpdateHeight(a);
48 UpdateHeight(b);
49 return b;
50}
51
52AVLTree LL(AVLTree a) {
53 AVLTree b = a->Left;
54 a->Left = b->Right;
55 b->Right = a;
56
57 UpdateHeight(a);
58 UpdateHeight(b);
59 return b;
60}
61
62AVLTree LR(AVLTree a) {
63 a->Left = RR(a->Left);
64 return LL(a);
65}
66AVLTree RL(AVLTree a) {
67 a->Right = LL(a->Right);
68 return RR(a);
69}
70
71AVLTree Insert(AVLTree t, ElementType item) {
72 if (!t) {
73 // 给叶子节点添加一个子节点的时候,走到这个部分。
74 AVLTree node = (AVLTree)malloc(sizeof(struct AVLNode));
75 node->Data = item;
76 node->Left = NULL;
77 node->Right = NULL;
78 node->Height = 1;
79 return node;
80 }
81 if (item > t->Data) {
82 t->Right = Insert(t->Right, item);
83 if (GetHeight(t->Right) - GetHeight(t->Left) == 2) {
84 if (item > t->Right->Data) {
85 t = RR(t);
86 } else {
87 t = RL(t);
88 }
89 }
90 } else {
91 t->Left = Insert(t->Left, item);
92 if (GetHeight(t->Left) - GetHeight(t->Right) == 2) {
93 if (item < t->Left->Data) {
94 t = LL(t);
95 } else {
96 t = LR(t);
97 }
98 }
99 }
100 t->Height = Max(GetHeight(t->Left), GetHeight(t->Right)) + 1;
101 return t;
102}
103void PreOrderTraversalByRecursive(AVLTree bt){
104 if (bt){
105 printf("%d ", bt->Data);
106 PreOrderTraversalByRecursive(bt->Left);
107 PreOrderTraversalByRecursive(bt->Right);
108 }
109}
110
111int main(){
112 AVLTree avlTree= NULL ;
113 //avlTree = CreateAvlTree();
114 avlTree= Insert(avlTree,1);
115 avlTree = Insert(avlTree,2) ;
116 avlTree= Insert(avlTree,3) ;
117 PreOrderTraversalByRecursive(avlTree);
118 printf("\n");
119 avlTree= Insert(avlTree,7) ;
120 PreOrderTraversalByRecursive(avlTree);
121 printf("\n");
122 avlTree= Insert(avlTree,6) ;
123 avlTree= Insert(avlTree,5) ;
124 avlTree= Insert(avlTree,0) ;
125 PreOrderTraversalByRecursive(avlTree);
126}
127/*
128 * =========================================================
129 one two three three_adjust(RR)
130 1 1 1 2
131 2 2 1 3
132 3
133 * =========================================================
134 four five five_adjust(RL)
135 2 2 2
136 1 3 1 3 1 6
137 7 7 3 7
138 6
139=========================================================
140 six six_adjust(RL)
141 2 3
142 1 6 2 6
143 3 7 1 5 7
144 5
145=========================================================
146 seven seven_adjust(LL)
147 3 3
148 2 6 1 6
149 1 5 7 0 2 5 7
150 0
151 */