平衡二叉树
1、平衡二叉树(AVL):它或者是一颗空树,左子树和右子树的深度之差不超过1,且他的左子树和右子树都是一颗平衡二叉树
2、平衡二叉树出现的原因:平衡二叉树就是在二叉排序树(BST)引入的,就是为了解决二叉排序树的不平衡性导致时间复杂度大大下降,AVL就保持住了BST的最好时间复杂度O(logn),所以每次插入和删除都要确保二叉树的平衡,很好的解决了二叉查找树退化成链表的问题,把插入查找删除的时间复杂度最好情况和最坏的情况都维持在了O(logn),但是频繁旋转会使插入和删除牺牲掉O(logn)左右的时间,相对二叉查找树来说,时间上稳定了很多。
3、平衡二叉树默认左孩子的值比双亲节点小,右孩子的值比双亲节点大(这句话也很重要)。由此在插入或者删除结点时,如何调整二叉树为平衡二叉树?这里就有四种情况
1、去判断每个结点的平衡因子,为2的结点要移动,如果一棵树有两个结点平衡因子都为2,移动下面的那个结点(这句话很重要)
LL:首先这个图的大小排序你能分辨出来吗:T1<Z<T2<X<T3<Y<T4(如果能分辨出来,以下内容你将会很好理解)
这是所谓的左左结构:x<y x>z 所以不平衡时把x放在中间,T3>X T3<Y 所以T3应该放在X的右边,Y的左边
LR:一样的道理z>x z<y 所以Z应该放在x、y的中间,T2>x T2<z; T3>zT3<y
RR:x放在y和z的中间,T3<x,T3>y
RL: Z<X Z>Y 所以z放在xy中间, T2>Y,T2<Z; T3>Z,T3<X
4、那既然说完上面的四种调整结构了,如何使用呢,用插入元素(90,66,65,98,100,88,105,102,110,103)构造一颗平衡二叉树,构造过程如下
5、既然插入说了,此处相信大家删除结点在调整为平衡二叉树一定会了吧,就不一一举例了
可运行代码

1 #ifndef BINARY_H 2 #define BINARY_H 3 4 typedef int TYPE; 5 typedef int BOOL; 6 7 typedef struct _BTNode 8 { 9 TYPE data; 10 int height; 11 struct _BTNode *lchild; 12 struct _BTNode *rchild; 13 } BTNode; 14 15 typedef struct _BTree 16 { 17 BTNode *phead; 18 19 void (*init)(struct _BTree *BT, TYPE head_value); 20 void (*exit)(struct _BTree *BT); 21 void (*print)(struct _BTree *BT, BTNode *phead); 22 23 BOOL(*add) 24 (struct _BTree *BT, BTNode *phead, TYPE value); 25 BOOL(*del) 26 (struct _BTree *BT, BTNode **phead, TYPE value); 27 BOOL(*del_tree) 28 (struct _BTree *BT, BTNode **phead); 29 BOOL(*alter) 30 (struct _BTree *BT, BTNode *phead, TYPE value,TYPE new_vlue); 31 BTNode *(*search)(struct _BTree *BT, BTNode *phead, TYPE value); 32 33 BTNode *(*search_min)(struct _BTree *BT, BTNode **phead, int flag); 34 BTNode *(*search_max)(struct _BTree *BT, BTNode **phead, int flag); 35 36 void (*pre_traverse)(struct _BTree *BT, BTNode *phead); 37 void (*mid_traverse)(struct _BTree *BT, BTNode *phead); 38 void (*last_traverse)(struct _BTree *BT, BTNode *phead); 39 40 // 实现AVL所需函数 41 int (*node_height)(struct _BTree *BT, BTNode *phead); 42 void (*height)(struct _BTree *BT, BTNode *phead); 43 int (*max_height)(int height1, int height2); 44 BTNode *(*singleRotateLL)(struct _BTree *BT, BTNode *phead); 45 BTNode *(*singleRotateRR)(struct _BTree *BT, BTNode *phead); 46 BTNode *(*doubleRotateLR)(struct _BTree *BT, BTNode *phead); 47 BTNode *(*doubleRotateRL)(struct _BTree *BT, BTNode *phead); 48 } BTree; 49 50 void tree_init(BTree *BT, TYPE value); 51 void tree_exit(BTree *BT); 52 53 #endif

1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 5 #include "binary.h" 6 7 void tree_init(BTree *BT, TYPE head_value); 8 void tree_exit(BTree *BT); 9 void tree_print(BTree *BT, BTNode *phead); 10 static BOOL tree_add(BTree *BT, BTNode *phead, TYPE value); 11 static BOOL tree_del(BTree *BT, BTNode **phead, TYPE value); 12 static BOOL tree_del_tree(BTree *BT, BTNode **phead); 13 static BOOL tree_alter(BTree *BT, BTNode *phead, TYPE value, TYPE new_value); 14 static BTNode *tree_search(BTree *BT, BTNode *phead, TYPE value); 15 static BTNode *tree_search_min (BTree *BT, BTNode **phead, int flag); 16 static BTNode *tree_search_max (BTree *BT, BTNode **phead,int flag); 17 static void tree_pre_traverse(BTree *BT, BTNode *phead); 18 static void tree_mid_traverse(BTree *BT, BTNode *phead); 19 static void tree_last_traverse(BTree *BT, BTNode *phead); 20 21 // 实现AVL所需函数 22 static int tree_node_height(BTree *BT, BTNode *phead); 23 static void tree_height(BTree *BT, BTNode *phead); 24 static int max_height(int height1, int height2); 25 static BTNode *singleRotateLL(BTree *BT, BTNode *phead); 26 static BTNode *singleRotateRR(BTree *BT, BTNode *phead); 27 static BTNode *doubleRotateLR(BTree *BT, BTNode *phead); 28 static BTNode *doubleRotateRL(BTree *BT, BTNode *phead); 29 30 // 初始化 31 void tree_init(BTree *BT, TYPE head_value) 32 { 33 BT->phead = (BTNode*)calloc(1, sizeof(BTNode)); 34 BT->phead->data = head_value; 35 36 BT->phead->lchild = BT->phead->rchild = NULL; 37 38 BT->add = tree_add; //??不是很懂 39 BT->del = tree_del; 40 BT->print = tree_print; 41 BT->del_tree = tree_del_tree; 42 BT->alter = tree_alter; 43 BT->search = tree_search; 44 BT->search_min = tree_search_min; 45 BT->search_max = tree_search_max; 46 BT->pre_traverse = tree_pre_traverse; 47 BT->mid_traverse = tree_mid_traverse; 48 BT->last_traverse = tree_last_traverse; 49 BT->exit = tree_exit; 50 51 BT->node_height = tree_node_height; 52 BT->height = tree_height; 53 BT->max_height = max_height; 54 BT->singleRotateRR = singleRotateRR; 55 BT->singleRotateLL = singleRotateLL; 56 BT->doubleRotateLR = doubleRotateLR; 57 BT->doubleRotateRL = doubleRotateRL; 58 } 59 60 // 结束操作 61 void tree_exit(BTree *BT) 62 { 63 if (BT != NULL) 64 { 65 BT->del_tree(BT, &BT->phead); 66 } 67 } 68 void tree_print(BTree *BT, BTNode *phead) 69 { 70 if (phead != NULL) 71 { 72 printf("%d\n", phead->data); // 打印头结点? 73 } 74 } 75 static BOOL tree_add(BTree *BT, BTNode *phead, TYPE value) 76 { // 按序插入结点 77 if (phead == NULL) 78 { 79 return 0; 80 } 81 if (phead->data == value) // 嗯哼? 82 { 83 return 0; 84 } 85 else 86 { 87 if (phead->data > value) 88 { 89 if (phead->lchild == NULL) 90 { 91 BTNode *newnode = (BTNode *)calloc(1, sizeof(BTNode)); 92 newnode->data = value; 93 newnode->lchild = newnode->rchild = NULL; 94 phead->lchild = newnode; 95 } 96 else 97 { 98 tree_add(BT, phead->lchild, value); 99 100 // 判断插入结点后是否平衡,并调整 101 BTNode *root; 102 if (phead = BT->phead) //>是否写的不对 103 { 104 root = phead; 105 } 106 else 107 { 108 root = phead->lchild; 109 } 110 if (tree_node_height(BT, root->lchild) - tree_node_height(BT, root->rchild) == 2) 111 { 112 if (root->lchild->data > value) 113 { 114 root = singleRotateLL(BT, root); 115 } 116 else 117 { 118 root = doubleRotateLR(BT, root); 119 } 120 } 121 phead = root; 122 } 123 } 124 else 125 { 126 if (phead->rchild == NULL) 127 { 128 BTNode *newnode = (BTNode *)calloc(1, sizeof(BTNode)); 129 newnode->data = value; 130 newnode->lchild = newnode->rchild = NULL; 131 phead->rchild = newnode; 132 } 133 else 134 { 135 tree_add(BT, phead->rchild, value); 136 137 // 判断插入结点是否平衡,并调整 138 BTNode *root; 139 if (phead = BT->phead) 140 { 141 root = phead; 142 } 143 else 144 { 145 root = phead->rchild; 146 } 147 if (tree_node_height(BT, root->rchild) - tree_node_height(BT, root->lchild) == 2) 148 { 149 if (root->rchild->data < value) 150 { 151 root = singleRotateRR(BT, root); 152 } 153 else 154 { 155 root = doubleRotateRL(BT, root); 156 } 157 } 158 phead = root; 159 } 160 } 161 phead->height = tree_node_height(BT, phead); 162 return 1; 163 } 164 return 0; 165 } 166 167 // 删除结点 168 static BOOL tree_del(BTree *BT, BTNode **phead, TYPE value) 169 { 170 BTNode *temp; 171 BTNode *root; 172 int flag;//标记结点,顶部结点为0,左边节点为-1,右边结点为1; 173 174 if(*phead == NULL) 175 { 176 return 0; 177 } 178 179 if (*phead == BT->phead) 180 { 181 flag = 0; 182 root = *phead; 183 } 184 else if ((*phead)->lchild != NULL) 185 { 186 flag = -1; 187 root = (*phead)->lchild; 188 } 189 else if ((*phead)->rchild != NULL) 190 { 191 flag = 1; 192 root = (*phead)->rchild; 193 } 194 else if ((*phead)->lchild == NULL && (*phead)->rchild == NULL) 195 { 196 root = *phead; 197 } 198 if (root->data == value) 199 { 200 if (root->lchild != NULL) 201 { 202 temp = BT->search_max(BT, &root->lchild, 1); 203 temp->lchild = root->lchild; 204 temp->rchild = root->rchild; 205 free(root); 206 root = temp; 207 if (flag == 0) 208 { 209 BT->phead = root; 210 } 211 else 212 { 213 (*phead)->lchild = root; 214 } 215 } 216 else if (root->rchild != NULL) 217 { 218 temp = BT->search_min(BT, &root->rchild, 1); 219 temp->lchild = root->lchild; 220 temp->rchild = root->rchild; 221 free(root); 222 root = temp; 223 if (flag == 0) 224 { 225 BT->phead = root; 226 } 227 else 228 { 229 (*phead)->rchild = root; 230 } 231 } 232 else 233 { 234 if (flag == 0) 235 { 236 free(*phead); 237 } 238 else if (flag = -1) 239 { 240 free((*phead)->lchild); 241 (*phead)->lchild = NULL; 242 } 243 else if (flag = 1) 244 { 245 free((*phead)->rchild); 246 (*phead)->rchild = NULL; 247 } 248 } 249 250 tree_height(BT, BT->phead);//删除结点,求节点的新高度 251 252 if (flag == 0) 253 { 254 return 1; 255 } 256 if (flag == -1) 257 { 258 if (tree_node_height(BT, (*phead)->rchild) - tree_node_height(BT, (*phead)->lchild) == 2) 259 { 260 if ((*phead)->rchild->rchild != NULL) 261 { 262 root = singleRotateRR(BT, *phead); 263 } 264 else 265 { 266 root = doubleRotateRL(BT, *phead); 267 } 268 } 269 } 270 else 271 { 272 if (tree_node_height(BT, (*phead)->lchild) - tree_node_height(BT, (*phead)->rchild) == 2) 273 { 274 if ((*phead)->lchild->lchild != NULL) 275 { 276 root = singleRotateLL(BT, *phead); 277 } 278 else 279 { 280 root = doubleRotateLR(BT, *phead); 281 } 282 } 283 } 284 return 1; 285 286 } 287 else if (root->data > value) 288 { 289 return BT->del(BT, &root->lchild, value); 290 } 291 else 292 { 293 return BT->del(BT, &root->rchild, value); 294 } 295 296 return 0; 297 } 298 299 // 删除二叉树 300 static BOOL tree_del_tree(BTree *BT, BTNode **phead) 301 { 302 if (*phead == NULL) 303 { 304 return 0; 305 } 306 if ((*phead)->lchild != NULL) 307 { 308 BT->del_tree(BT, &(*phead)->lchild); 309 } 310 if ((*phead)->rchild != NULL) 311 { 312 BT->del_tree(BT, &(*phead)->rchild); 313 } 314 free(*phead); 315 *phead = NULL; 316 317 return 1; 318 } 319 320 // 更改结点的值(先删除,后插入) 321 static BOOL tree_alter(BTree *BT, BTNode *phead, TYPE value, TYPE new_value) 322 { 323 if (phead == NULL) 324 { 325 return 0; 326 } 327 if (value == new_value) 328 { 329 return 1; 330 } 331 if (BT->del(BT, &phead, value) != 0) 332 { 333 if (BT->add(BT, phead, new_value) != 0) 334 { 335 return 1; 336 } 337 else 338 { 339 return 0; 340 } 341 } 342 else 343 { 344 return 0; 345 } 346 } 347 348 // 查找结点 349 static BTNode *tree_search(BTree *BT, BTNode *phead, TYPE value) 350 { 351 BTNode *temp; 352 353 if (phead == NULL) 354 { 355 return NULL; 356 } 357 if (phead->data == value) 358 { 359 return phead; 360 } 361 if (phead->lchild != NULL) 362 { 363 temp = BT->search(BT, phead->lchild, value); 364 if (temp != NULL) 365 { 366 return temp; 367 } 368 } 369 if (phead->rchild != NULL) 370 { 371 temp = BT->search(BT, phead->rchild, value); 372 373 if (temp != NULL) 374 { 375 return temp; 376 } 377 } 378 return NULL; 379 } 380 381 // 查找最小结点 382 static BTNode *tree_search_min(BTree *BT, BTNode **phead, int flag) 383 { 384 BTNode *temp; 385 386 if (*phead == NULL) 387 { 388 return NULL; 389 } 390 391 if ((*phead)->lchild == NULL) // 咩看懂 392 { 393 temp = *phead; 394 if (flag == 1) 395 { 396 *phead = (*phead)->rchild; 397 } 398 return temp; 399 } 400 else 401 { 402 return BT->search_min(BT, &(*phead)->lchild, flag); // 平衡二叉树一直往左找最小值 403 } 404 } 405 406 // 查找最大节点 407 static BTNode *tree_search_max(BTree *BT, BTNode **phead, int flag) 408 { 409 BTNode *temp; 410 411 if (*phead == NULL) 412 { 413 return NULL; 414 } 415 416 if ((*phead)->lchild == NULL) // 咩看懂 417 { 418 temp = *phead; 419 if (flag == 1) 420 { 421 *phead = (*phead)->lchild; 422 } 423 return temp; 424 } 425 else 426 { 427 return BT->search_min(BT, &(*phead)->rchild, flag); // 往右找最大值 428 } 429 } 430 431 // 先序遍历二叉树 432 static void tree_pre_traverse(BTree *BT, BTNode *phead) 433 { 434 if (phead == NULL) 435 { 436 return; 437 } 438 BT->print(BT, phead); 439 if (phead->lchild != NULL) 440 { 441 BT->pre_traverse(BT, phead->lchild); // 觉得BT指向很奇怪 442 } 443 if (phead->rchild != NULL) 444 { 445 BT->pre_traverse(BT, phead->rchild); 446 } 447 } 448 449 // 中序遍历二叉树 450 static void tree_mid_traverse(BTree *BT, BTNode *phead) 451 { 452 if (phead == NULL) 453 { 454 return; 455 } 456 if (phead->lchild != NULL) 457 { 458 BT->mid_traverse(BT, phead->lchild); 459 } 460 BT->print(BT, phead); 461 if (phead->rchild != NULL) 462 { 463 BT->mid_traverse(BT, phead->rchild); 464 } 465 } 466 467 // 后续遍历二叉树 468 static void tree_last_traverse(BTree *BT, BTNode *phead) 469 { 470 if (phead == NULL) 471 { 472 return; 473 } 474 475 if (phead->lchild != NULL) 476 { 477 BT->last_traverse(BT, phead->lchild); 478 } 479 if (phead->rchild != NULL) 480 { 481 BT->last_traverse(BT, phead->rchild); 482 } 483 BT->print(BT, phead); 484 } 485 486 // 求结点的高度,写成函数解决指针为空的情况,默认空节点的高度为-1,只有一个根节点的高度为0,多一层高度加一 487 static int tree_node_height(BTree *BT, BTNode *phead) 488 { 489 if (phead != NULL) 490 { 491 if (phead->lchild == NULL && phead->rchild == NULL) 492 { 493 return 0; 494 } 495 else 496 { 497 return phead->height = max_height((tree_node_height(BT, phead->lchild)), (tree_node_height(BT, phead->rchild))) + 1; 498 } 499 } 500 else 501 { 502 return -1; 503 } 504 } 505 506 // 遍历求树中每个节点的高度 507 static void tree_height(BTree *BT, BTNode *phead) 508 { 509 if (phead == NULL) 510 { 511 return; 512 } 513 tree_node_height(BT, phead); 514 if (phead->lchild != NULL) 515 { 516 tree_node_height(BT, phead->lchild); 517 } 518 if (phead->rchild != NULL) 519 { 520 tree_node_height(BT, phead->rchild); 521 } 522 } 523 524 // 求两个高度的最大值 525 static int max_height(int height1, int height2) 526 { 527 if (height1 > height2) 528 { 529 return height1; 530 } 531 else 532 { 533 return height2; 534 } 535 } 536 537 // 左左情况 538 static BTNode *singleRotateLL(BTree *BT, BTNode *phead) 539 { 540 BTNode *temp; 541 if (phead == NULL) 542 { 543 return 0; 544 } 545 temp = phead->lchild; 546 547 if (temp->rchild != NULL) 548 { 549 phead->lchild = temp->rchild; 550 phead->lchild->height = tree_node_height(BT, phead->lchild); 551 } 552 else 553 { 554 phead->lchild = NULL; 555 } 556 557 temp->rchild = phead; 558 if (temp->rchild->data == BT->phead->data) 559 { 560 BT->phead = temp; 561 } 562 phead = temp; 563 temp->rchild->height = tree_node_height(BT, temp->rchild); 564 temp->height = tree_node_height(BT, temp); 565 phead->height = tree_node_height(BT, phead); 566 567 return phead; 568 } 569 570 // 右右 571 static BTNode *singleRotateRR(BTree *BT, BTNode *phead) 572 { 573 BTNode *temp; 574 if (phead == NULL) 575 { 576 return 0; 577 } 578 temp = phead->rchild; 579 580 if (temp->lchild != NULL) 581 { 582 phead->rchild = temp->lchild; 583 phead->rchild->height = tree_node_height(BT, phead->rchild); 584 } 585 else 586 { 587 phead->rchild = NULL; 588 } 589 temp->lchild = phead; 590 if (temp->lchild->data == BT->phead->data) 591 { 592 BT->phead = temp; 593 } 594 phead = temp; 595 temp->lchild->height = tree_node_height(BT, temp->lchild); 596 temp->height = tree_node_height(BT, temp); 597 phead->height = tree_node_height(BT, phead); 598 599 return phead; 600 } 601 602 static BTNode *doubleRotateLR(BTree *BT, BTNode *phead) 603 { 604 BTNode *temp; 605 if (phead == NULL) 606 { 607 return 0; 608 } 609 temp = phead->lchild; 610 phead->lchild = singleRotateRR(BT, temp); 611 temp = phead; 612 phead = singleRotateLL(BT, temp); 613 614 return phead; 615 } 616 617 static BTNode *doubleRotateRL(BTree *BT, BTNode *phead) 618 { 619 BTNode *temp; 620 if (phead == NULL) 621 { 622 return 0; 623 } 624 temp = phead->rchild; 625 phead->rchild = singleRotateLL(BT, temp); 626 temp = phead; 627 phead = singleRotateRR(BT, temp); 628 629 return phead; 630 } 631 632 int main() 633 { 634 BTree testtree; 635 testtree.init = tree_init; 636 testtree.init(&testtree,9); 637 638 testtree.add(&testtree,testtree.phead,4); 639 testtree.add(&testtree,testtree.phead,5); 640 testtree.add(&testtree,testtree.phead,6); 641 testtree.add(&testtree,testtree.phead,1); 642 testtree.add(&testtree,testtree.phead,7); 643 testtree.add(&testtree,testtree.phead,8); 644 testtree.add(&testtree,testtree.phead,11); 645 testtree.add(&testtree,testtree.phead,10); 646 647 testtree.pre_traverse(&testtree,testtree.phead); 648 printf("\n"); 649 testtree.mid_traverse(&testtree,testtree.phead); 650 printf("\n"); 651 testtree.last_traverse(&testtree,testtree.phead); 652 printf("\n"); 653 printf("%d\n",(testtree.search(&testtree,testtree.phead,8)->data)); 654 //前面的可以正常运行 655 656 testtree.alter(&testtree,testtree.phead,9,2); 657 testtree.del(&testtree,&testtree.phead,4); 658 testtree.del(&testtree,&testtree.phead,1); 659 testtree.del(&testtree,&testtree.phead,6); 660 661 662 testtree.pre_traverse(&testtree,testtree.phead); 663 printf("\n"); 664 testtree.mid_traverse(&testtree,testtree.phead); 665 printf("\n"); 666 testtree.last_traverse(&testtree,testtree.phead); 667 printf("\n"); 668 669 return 0; 670 671 }
感谢观看
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)