在书上看了平衡二叉树的代码后,发现前人的智慧真是无限。但是因为一次性给出的最完美的代码让人有时候看不太懂...
后来经过仔细推敲,才慢慢发现了其中的奥秘。一开始并不知道关于平衡二叉树的平衡因子BF是怎么修改的,后来才发现关于平衡二叉树的最重要的一句话:在构建平衡二叉树的过程中,每当插入一个结点时,先检查是否因插入而破坏了树的平衡性,若是,则找出最小不平衡子树,在保持二叉排序树特性的前提下,调整关系。
这句话意味着:只要破坏了平衡性,就马上修改使得二叉树重新平衡,意思就是只要修改了最小不平衡树就可以使得整个二叉树重新平衡.
下面借用书上的代码进行解释说明,说明在代码后面
[cpp] view plaincopy
1. #include "stdio.h"
2. #include "stdlib.h"
3. #include "io.h"
4. #include "math.h"
5. #include "time.h"
6.
7. #define OK 1
8. #define ERROR 0
9. #define TRUE 1
10. #define FALSE 0
11. #define MAXSIZE 100 /* 存储空间初始分配量 */
12.
13. typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
14.
15.
16. /* 二叉树的二叉链表结点结构定义 */
17. typedef struct BiTNode /* 结点结构 */
18. {
19. int data; /* 结点数据 */
20. int bf; /* 结点的平衡因子 */
21. struct BiTNode *lchild, *rchild; /* 左右孩子指针 */
22. } BiTNode, *BiTree;
23.
24.
25. /* 对以p为根的二叉排序树作右旋处理, */
26. /* 处理之后p指向新的树根结点,即旋转处理之前的左子树的根结点 */
27. void R_Rotate(BiTree *P)
28. {
29. BiTree L;
30. L=(*P)->lchild; /* L指向P的左子树根结点 */
31. (*P)->lchild=L->rchild; /* L的右子树挂接为P的左子树 */
32. L->rchild=(*P);
33. *P=L; /* P指向新的根结点 */
34. }
35.
36. /* 对以P为根的二叉排序树作左旋处理, */
37. /* 处理之后P指向新的树根结点,即旋转处理之前的右子树的根结点0 */
38. void L_Rotate(BiTree *P)
39. {
40. BiTree R;
41. R=(*P)->rchild; /* R指向P的右子树根结点 */
42. (*P)->rchild=R->lchild; /* R的左子树挂接为P的右子树 */
43. R->lchild=(*P);
44. *P=R; /* P指向新的根结点 */
45. }
46.
47. #define LH +1 /* 左高 */
48. #define EH 0 /* 等高 */
49. #define RH -1 /* 右高 */
50.
51. /* 对以指针T所指结点为根的二叉树作左平衡旋转处理 */
52. /* 本算法结束时,指针T指