首页 > 代码库 > 二叉查找树
二叉查找树
相关性质 可查看维基百科"二叉查找树"
关键性质:设root为二叉查找树的结点
如果a是root的左结点 key[a] < key[root]
如果a是root的有结点 key[root] < key[a]
下述实现基于上面的图(丑了点,但不影响阅读,有向且父节点与子节点关系清晰)
1 #include <iostream> 2 #include <crtdbg.h> 3 using namespace std; 4 /*二叉查找树*/ 5 /*实现中假设关键元素互不相同*/ 6 typedef int DataType; 7 8 struct TreeNode 9 { 10 TreeNode() 11 { 12 right = NULL; 13 left = NULL; 14 } 15 DataType data; 16 TreeNode *right; 17 TreeNode *left; 18 }; 19 20 struct BiTree 21 { 22 TreeNode *root; 23 24 BiTree() 25 { 26 root=NULL; 27 } 28 ~BiTree() 29 { 30 Destroy(root); 31 root = NULL; 32 } 33 void Destroy(TreeNode *p) 34 { 35 if (p == NULL) return; 36 37 Destroy(p->left); 38 Destroy(p->right); 39 delete p; 40 } 41 /*先确定父结点位置,在确定子节点位置*/ 42 void Insert(DataType data) 43 { 44 TreeNode *pTemp = NULL; 45 TreeNode *p = root; 46 while(p != NULL) 47 { 48 pTemp = p; 49 if (data < p->data) 50 { 51 p = p->left; 52 } 53 else 54 { 55 p = p->right; 56 } 57 } 58 TreeNode *pNew = new TreeNode; 59 pNew->data =http://www.mamicode.com/ data; 60 if (pTemp == NULL) 61 { 62 root = pNew; 63 } 64 else 65 { 66 if (data < pTemp->data) 67 { 68 pTemp->left = pNew; 69 } 70 else 71 { 72 pTemp->right = pNew; 73 } 74 } 75 } 76 /*考虑3种情况,要删除的结点有两子节点,只有一个子节点,没有子节点*/ 77 void Delete(DataType data) 78 { 79 TreeNode *p = Find(data); 80 TreeNode *parent = GetParent(root,p); 81 82 if (p->left == NULL && p->right == NULL)/*子结点都为空*/ 83 { 84 if (parent !=NULL) 85 { 86 if (parent->left == p) 87 { 88 parent->left = NULL; 89 } 90 else 91 { 92 parent->right = NULL; 93 } 94 } 95 else 96 { 97 root = NULL; 98 } 99 delete p; 100 } 101 else if (p->left == NULL || p->right == NULL)/*只有一个子结点为空*/ 102 { 103 if (parent != NULL) 104 { 105 if (p->left != NULL) 106 { 107 if (parent->left == p) 108 { 109 parent->left = p->left; 110 } 111 else 112 { 113 parent->right = p->left; 114 } 115 } 116 else 117 { 118 if (parent->left == p) 119 { 120 parent->left = p->right; 121 } 122 else 123 { 124 parent->right = p->right; 125 } 126 } 127 delete p; 128 p = NULL; 129 } 130 else/*要删除的结点为根结点*/ 131 { 132 if (p->left != NULL) 133 { 134 p->data = http://www.mamicode.com/p->left->data; 135 delete p->left; 136 p->left = NULL; 137 } 138 else 139 { 140 p->data = http://www.mamicode.com/p->right->data; 141 delete p->right; 142 p->right = NULL; 143 } 144 } 145 } 146 else/*子结点都不为空*/ 147 { 148 TreeNode *pAfter = TreeAfter(p); 149 TreeNode *pAfterParent = GetParent(root, pAfter); 150 151 if (pAfterParent != NULL)/*不为头结点*/ 152 { 153 if (pAfter->right != NULL)/* p的后继结点不可能有左子结点*/ 154 { 155 if (pAfterParent->left == pAfter) 156 { 157 pAfterParent->left = pAfter->right; 158 } 159 else 160 { 161 pAfterParent->right = pAfter->right; 162 } 163 } 164 else 165 { 166 if (pAfterParent->left == pAfter) 167 { 168 pAfterParent->left = NULL; 169 } 170 else 171 { 172 pAfterParent->right = NULL; 173 } 174 } 175 p->data = http://www.mamicode.com/pAfter->data; 176 } 177 else 178 { 179 p->data = http://www.mamicode.com/pAfter->data; 180 p->right = NULL; 181 } 182 delete pAfter; 183 } 184 } 185 /*非线性结构转换成线性结构(内存是线性的) 有3种方法 先序 中序 后序*/ 186 /*中序遍历*/ 187 void InOrderTree(TreeNode *p) 188 { 189 if (p == NULL) return ; 190 191 InOrderTree(p->left); 192 cout << p->data << endl; 193 InOrderTree(p->right); 194 } 195 /*递归版本*/ 196 TreeNode* Search(TreeNode *p, DataType key) 197 { 198 if (p == NULL || p->data =http://www.mamicode.com/= key) 199 return p; 200 201 if (key < p->data) 202 { 203 return Search(p->left, key); 204 } 205 else 206 { 207 return Search(p->right, key); 208 } 209 } 210 /*非递归版本*/ 211 TreeNode* Find(DataType key) 212 { 213 TreeNode *p = root; 214 while(p != NULL && p->data != key) 215 { 216 if (key < p->data) 217 { 218 p = p->left; 219 } 220 else 221 { 222 p = p->right; 223 } 224 } 225 return p; 226 } 227 /*寻找最小值*/ 228 TreeNode* Minimum(TreeNode *p) 229 { 230 TreeNode *pTemp = p; 231 while(pTemp != NULL) 232 { 233 p = pTemp; 234 pTemp = p->left; 235 } 236 return p; 237 } 238 /*寻找最大值*/ 239 TreeNode* Maximum(TreeNode *p) 240 { 241 TreeNode *pTemp = p; 242 while(pTemp != NULL) 243 { 244 p = pTemp; 245 pTemp = p->right; 246 } 247 return p; 248 } 249 /*获取父节点*/ 250 TreeNode * GetParent(TreeNode *parent, TreeNode *p) 251 { 252 if (parent == NULL || parent == p) 253 return NULL; 254 if (parent->left == p || parent->right == p) 255 { 256 return parent; 257 } 258 TreeNode *ret = GetParent(parent->left, p); 259 if(ret) 260 return ret; 261 return GetParent(parent->right, p); 262 } 263 /*寻找前趋(关键字都不相同) x的前趋为小于key[x]的 最大关键值 264 考虑两种情况 265 1 如果结点x的左子树非空,则x的前趋为左子树中的右结点 266 2 如果结点x的左子树为空,则x的前趋为x的祖先结点,即x的父节点且父结点为其父结点的右子结点 267 */ 268 TreeNode *TreePre(TreeNode *p) 269 { 270 if (p->left) 271 { 272 return Maximum(p->left); 273 } 274 TreeNode *parent = GetParent(root,p); 275 while(parent != NULL && p == parent->left) 276 { 277 p = parent; 278 parent = GetParent(root,parent); 279 } 280 return parent; 281 } 282 /*寻找后继(关键字都不相同) x的后继为大于key[x]的 最小关键值 283 考虑两种情况 284 1 如果结点x的右子树非空,则x的后继为右子树中的左结点 285 2 如果结点x的右子树为空,则x的后继为x的祖先结点,即x的父节点且父结点为其父结点的左子结点 286 */ 287 TreeNode *TreeAfter(TreeNode *p) 288 { 289 if (p->right) 290 { 291 return Minimum(p->right); 292 } 293 TreeNode *parent = GetParent(root,p); 294 while(parent != NULL && p == parent->right) 295 { 296 p = parent; 297 parent = GetParent(root,parent); 298 } 299 return parent; 300 } 301 }; 302 void main() 303 { 304 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); 305 306 BiTree biTree; 307 /*测试插入*/ 308 biTree.Insert(15); 309 biTree.Insert(6); 310 biTree.Insert(3); 311 biTree.Insert(7); 312 biTree.Insert(2); 313 biTree.Insert(4); 314 biTree.Insert(13); 315 biTree.Insert(9); 316 biTree.Insert(18); 317 biTree.Insert(17); 318 biTree.Insert(20); 319 biTree.InOrderTree(biTree.root); 320 321 /*测试最大最小*/ 322 cout << endl; 323 TreeNode * p = NULL; 324 p = biTree.Maximum(biTree.root); 325 cout << p->data << endl; 326 p = biTree.Minimum(biTree.root); 327 cout << p->data << endl; 328 329 /*测试两种find 以及获取父节点GetParent*/ 330 cout <<endl; 331 TreeNode *p2 = NULL; 332 p = biTree.Find(17); 333 if (p != NULL) 334 { 335 p2 = biTree.GetParent(biTree.root, p); 336 cout << p2->data << endl; 337 } 338 p = biTree.Find(20); 339 if (p != NULL) 340 { 341 cout << biTree.GetParent(biTree.root, p)->data << endl; 342 } 343 344 /*测试 9前趋、 13后继*/ 345 cout <<endl; 346 TreeNode *p3 = NULL; 347 p3 = biTree.TreePre(biTree.Find(9)); 348 if ( p3 != NULL) 349 { 350 cout << p3->data << endl; 351 } 352 p3 = biTree.TreeAfter(biTree.Find(13)); 353 if ( p3 != NULL) 354 { 355 cout << p3->data << endl; 356 } 357 358 /*测试 删除 3中情况*/ 359 cout <<endl; 360 biTree.Delete(6); /*有两结点*/ 361 biTree.Delete(13); /*只有一个子节点*/ 362 biTree.Delete(20); /*没有子节点*/ 363 biTree.InOrderTree(biTree.root); 364 365 system("pause"); 366 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。