PAT 1066 Root of AVL Tree
10354 ワード
#include <cstdio>
#include <cstdlib>
class Node {
public:
Node* L;
Node* R;
int height;
int data;
Node(int val, Node* l = NULL, Node* r = NULL, int h = 0): data(val), L(l), R(r), height(h) {}
};
inline int height(Node* node) {
if (node == NULL) return -1;
return node->height;
}
inline int max(int a, int b) {return a>b?a:b;}
/* K2 is the first node violates the AVL property, K1 is its left node
violation is caused by insert a node into the K1's right sub-tree
(K2) (K1)
/ LL-rotate / \
(K1) --------------> (new) (K2)
/
(new)
*/
Node* rotateLL(Node* root) {
Node* K1 = root->L;
Node* K2 = root;
Node* k1_rsub = K1->R;
K1->R = K2;
K2->L = k1_rsub;
K1->height = max(height(K1->L), height(K1->R)) + 1;
K2->height = max(height(K2->L), height(K2->R)) + 1;
return K1;
}
/* K1 is the first node violates the AVL property, K2 is its right node
violation is caused by insert a node into the K2's left sub-tree
(K1) (K2)
\ RR-rotate / \
(K2) ----------------> (K1) (new)
\
(new)
*/
Node* rotateRR(Node* root) {
Node* K1 = root;
Node* K2 = root->R;
Node* k2_lsub = K2->L;
K2->L = K1;
K1->R = k2_lsub;
K1->height = max(height(K1->L), height(K1->R)) + 1;
K2->height = max(height(K2->L), height(K2->R)) + 1;
return K2;
}
/*
first do LL rotate on K3, then do RR rotate on K1
(K1) (K1) (K2)
\ \ / \
(K3) ------> (K2) --------> (K1) (K3)
/ \
(K2) (K3)
*/
Node* rotateRL(Node* root) {
Node* K1 = root;
Node* K2 = root->R->L;
Node* K3 = root->R;
K1->R = rotateLL(K3);
return rotateRR(K1);
}
/*
first do RR rotate on K1, then do LL rotate on K3
(K3) (K3) (K2)
/ / / \
(K1) ------> (K2) ------> (K1) (K3)
\ /
(K2) (K1)
*/
Node* rotateLR(Node* root) {
Node* K1 = root->L;
Node* K2 = root->L->R;
Node* K3 = root;
K3->L = rotateRR(K1);
return rotateLL(K3);
}
Node* insert(Node* root, int value) {
if (root == NULL) {
return new Node(value);
}
if (value < root->data) {
root->L = insert(root->L, value);
// do AVL property check
if (height(root->L) - height(root->R) == 2) {
if (value < root->L->data) {
// LL case, single rotation
root = rotateLL(root);
} else if (value > root->L->data) {
// LR case, double rotation
root = rotateLR(root);
}
}
} else if (value > root->data ){
root->R = insert(root->R, value);
// do AVL property check
if (height(root->R) - height(root->L) == 2) {
if (value > root->R->data) {
// RR case, single rotation
root = rotateRR(root);
} else if (value < root->R->data) {
// RL case, double rotation
root = rotateRL(root);
}
}
} else {
// equal, do nothing
}
root->height= max(height(root->L), height(root->R)) + 1;
return root;
}
int main() {
Node* r = NULL;
int N;
scanf("%d", &N);
for (int i=0; i<N; i++) {
int d;
scanf("%d", &d);
r = insert(r, d);
}
if (r != NULL) {
printf("%d", r->data);
}
return 0;
}
初めて自分でAVLツリーを書きます.データStructures and Alogrithm Analysis in C第2版のAVLツリーのコードを参照してください.