DS4

Problem A

向空AVL树插入 3,1,4,6,9,2,5,7

在插入9前,与BST相同
图示:

按BST插入方法插入9
图示:

此时,0003节点左右子树高度差超过1,执行旋转树操作。
图示:

后续插入同BST
图示:


Problem B

单旋转代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
PTNode rightRotate(PTNode y) {
PTNode x = y->LChild;
PTNode xr = x->RChild;

x->RChild = y;
y->LChild = xr;

x->height = height(x);
y->height = height(y);

return x;
}

PTNode leftRotate(PTNode y) {
PTNode x = y->RChild;
PTNode xl = x->LChild;

x->LChild = y;
y->RChild = xl;

x->height = height(x);
y->height = height(y);

return x;
}

双旋转基本操作与单旋转相同,具体实现代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//LL
if (bf > 1 && data < node->LChild->data) {
return rightRotate(node);
}
//RR
if (bf < -1 && data > node->RChild->data) {
return leftRotate(node);
}
//LR
if (bf > 1 && data > node->LChild->data) {
node->LChild = leftRotate(node->LChild);
return rightRotate(node);
}
//RL
if (bf < -1 && data < node->RChild->data) {
node->RChild = rightRotate(node->RChild);
return leftRotate(node);
}

A/B整体实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include <stdio.h>
#include <stdlib.h>

typedef struct Node *PTNode;
typedef struct Node {
int data;
PTNode LChild;
PTNode RChild;
int height;
} Node;

int max(int a, int b) {
return a > b ? a : b;
}

int height(Node *root) { //可能有问题️
if (root == NULL) {
return 0;
}
return 1 + max(height(root->LChild), height(root->RChild));
}

PTNode newNode(int data) {
PTNode newNode = (PTNode) malloc(sizeof(Node));
newNode->data = data;
newNode->LChild = newNode->RChild = NULL;
newNode->height = 0;
return newNode;
}

int getBalanceFactor(PTNode root) {
if (root == NULL) {
return 0;
}
return height(root->LChild) - height(root->RChild);
}

PTNode rightRotate(PTNode y) {
PTNode x = y->LChild;
PTNode xr = x->RChild;

x->RChild = y;
y->LChild = xr;

x->height = height(x);
y->height = height(y);

return x;
}

PTNode leftRotate(PTNode y) {
PTNode x = y->RChild;
PTNode xl = x->LChild;

x->LChild = y;
y->RChild = xl;

x->height = height(x);
y->height = height(y);

return x;
}

PTNode insert(PTNode node, int data) {
if (node == NULL) {
return newNode(data);
}
if (data < node->data) {
node->LChild = insert(node->LChild, data);
}
else if (data > node->data) {
node->RChild = insert(node->RChild, data);
}
else {
return node; //值已经存在
}

node->height = height(node);

int bf = getBalanceFactor(node);

//LL
if (bf > 1 && data < node->LChild->data) {
return rightRotate(node);
}

//RR
if (bf < -1 && data > node->RChild->data) {
return leftRotate(node);
}

//LR
if (bf > 1 && data > node->LChild->data) {
node->LChild = leftRotate(node->LChild);
return rightRotate(node);
}

//RL
if (bf < -1 && data < node->RChild->data) {
node->RChild = rightRotate(node->RChild);
return leftRotate(node);
}

return node;
}

void inOrder(PTNode root) {
if (root != NULL) {
inOrder(root->LChild);
printf("%d,", root->data);
inOrder(root->RChild);
}
}

void preOrder(PTNode root) {
if (root != NULL) {
printf("%d,", root->data);
preOrder(root->LChild);
preOrder(root->RChild);
}
}

int main() {
int n;
scanf("%d,", &n);
PTNode root = newNode(n);
while (scanf("%d,", &n) == 1) {
root = insert(root, n);
}
preOrder(root);
return 0;
}

Problem C

设用于通信的电文仅由8个字母组成,字母在电文中出现的频率分别为7、19、2、6、32、3、21、10,根据这些频率作为权值构造哈夫曼树

构造哈夫曼树过程:

  1. 从森林中选取权值最小两棵树作子树构造新二叉树
  2. 新树的值为两子树权值之和
  3. 构造后的树放回森林
  4. 重复操作选取最小权值树

图示:

字符对应编码:

  • c:10000
  • f:10001
  • d:1001
  • a:1010
  • h:1011
  • b:00
  • g:01
  • e:11

EOF