更新平衡
This commit is contained in:
parent
dda94299d0
commit
7cf9e6665f
|
@ -3,3 +3,4 @@
|
|||
template/*
|
||||
*.zip
|
||||
*/datas/*
|
||||
*/tempCodeRunnerFile.c
|
283
7/s3.c
283
7/s3.c
|
@ -1 +1,282 @@
|
|||
// todo
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct Tree {
|
||||
int val;
|
||||
struct Tree *l, *r;
|
||||
struct Tree *parent;
|
||||
int height;
|
||||
int balance;
|
||||
} Tree;
|
||||
|
||||
int n;
|
||||
int m;
|
||||
|
||||
// 获取节点高度
|
||||
int getHeight(Tree *root) {
|
||||
if (root == NULL)
|
||||
return 0;
|
||||
return root->height;
|
||||
}
|
||||
|
||||
// 更新节点高度和平衡因子
|
||||
void updateHeight(Tree *root) {
|
||||
if (root == NULL)
|
||||
return;
|
||||
int l = getHeight(root->l);
|
||||
int r = getHeight(root->r);
|
||||
root->height = (l > r ? l : r) + 1;
|
||||
root->balance = l - r;
|
||||
}
|
||||
|
||||
// 左旋操作
|
||||
Tree *leftRotate(Tree *root) {
|
||||
Tree *newRoot = root->r;
|
||||
root->r = newRoot->l;
|
||||
if (newRoot->l != NULL)
|
||||
newRoot->l->parent = root;
|
||||
newRoot->l = root;
|
||||
newRoot->parent = root->parent;
|
||||
root->parent = newRoot;
|
||||
updateHeight(root);
|
||||
updateHeight(newRoot);
|
||||
return newRoot;
|
||||
}
|
||||
|
||||
// 右旋操作
|
||||
Tree *rightRotate(Tree *root) {
|
||||
Tree *newRoot = root->l;
|
||||
root->l = newRoot->r;
|
||||
if (newRoot->r != NULL)
|
||||
newRoot->r->parent = root;
|
||||
newRoot->r = root;
|
||||
newRoot->parent = root->parent;
|
||||
root->parent = newRoot;
|
||||
updateHeight(root);
|
||||
updateHeight(newRoot);
|
||||
return newRoot;
|
||||
}
|
||||
|
||||
// 左右旋操作
|
||||
Tree *leftRightRotate(Tree *root) {
|
||||
root->l = leftRotate(root->l);
|
||||
return rightRotate(root);
|
||||
}
|
||||
|
||||
// 右左旋操作
|
||||
Tree *rightLeftRotate(Tree *root) {
|
||||
root->r = rightRotate(root->r);
|
||||
return leftRotate(root);
|
||||
}
|
||||
|
||||
// 插入节点
|
||||
Tree *insertNode(Tree *root, int val) {
|
||||
if (root == NULL) {
|
||||
Tree *tmp = (Tree *)malloc(sizeof(Tree));
|
||||
tmp->val = val;
|
||||
tmp->l = NULL;
|
||||
tmp->r = NULL;
|
||||
tmp->parent = NULL;
|
||||
tmp->height = 1;
|
||||
tmp->balance = 0;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
if (val < root->val) {
|
||||
root->l = insertNode(root->l, val);
|
||||
root->l->parent = root;
|
||||
} else {
|
||||
root->r = insertNode(root->r, val);
|
||||
root->r->parent = root;
|
||||
}
|
||||
|
||||
updateHeight(root);
|
||||
if (root->balance > 1) {
|
||||
if (val < root->l->val) {
|
||||
return rightRotate(root);
|
||||
} else {
|
||||
return leftRightRotate(root);
|
||||
}
|
||||
} else if (root->balance < -1) {
|
||||
if (val > root->r->val) {
|
||||
return leftRotate(root);
|
||||
} else {
|
||||
return rightLeftRotate(root);
|
||||
}
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
// 删除节点
|
||||
Tree *deleteNode(Tree *root, int val) {
|
||||
if (root == NULL)
|
||||
return NULL;
|
||||
|
||||
if (val < root->val) {
|
||||
root->l = deleteNode(root->l, val);
|
||||
} else if (val > root->val) {
|
||||
root->r = deleteNode(root->r, val);
|
||||
} else {
|
||||
if (root->l == NULL && root->r == NULL) {
|
||||
free(root);
|
||||
return NULL;
|
||||
} else if (root->l == NULL) {
|
||||
Tree *temp = root->r;
|
||||
free(root);
|
||||
return temp;
|
||||
} else if (root->r == NULL) {
|
||||
Tree *temp = root->l;
|
||||
free(root);
|
||||
return temp;
|
||||
} else {
|
||||
Tree *minNode = root->r;
|
||||
while (minNode->l != NULL)
|
||||
minNode = minNode->l;
|
||||
root->val = minNode->val;
|
||||
root->r = deleteNode(root->r, minNode->val);
|
||||
}
|
||||
}
|
||||
|
||||
updateHeight(root);
|
||||
if (root->balance > 1) {
|
||||
if (getHeight(root->l->l) >= getHeight(root->l->r)) {
|
||||
return rightRotate(root);
|
||||
} else {
|
||||
return leftRightRotate(root);
|
||||
}
|
||||
} else if (root->balance < -1) {
|
||||
if (getHeight(root->r->r) >= getHeight(root->r->l)) {
|
||||
return leftRotate(root);
|
||||
} else {
|
||||
return rightLeftRotate(root);
|
||||
}
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
void makeTree(Tree *root, int val) {
|
||||
if (val < root->val) {
|
||||
if (root->l == NULL) {
|
||||
root->l = (Tree *)malloc(sizeof(Tree));
|
||||
root->l->val = val;
|
||||
root->l->l = NULL;
|
||||
root->l->r = NULL;
|
||||
root->l->parent = root;
|
||||
root->l->height = root->height + 1;
|
||||
} else {
|
||||
makeTree(root->l, val);
|
||||
}
|
||||
} else {
|
||||
if (root->r == NULL) {
|
||||
root->r = (Tree *)malloc(sizeof(Tree));
|
||||
root->r->val = val;
|
||||
root->r->l = NULL;
|
||||
root->r->r = NULL;
|
||||
root->r->parent = root;
|
||||
root->r->height = root->height + 1;
|
||||
|
||||
} else {
|
||||
makeTree(root->r, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 中序遍历
|
||||
void inOrder(Tree *root) {
|
||||
if (root == NULL)
|
||||
return;
|
||||
inOrder(root->l);
|
||||
printf("%d ", root->val);
|
||||
inOrder(root->r);
|
||||
}
|
||||
|
||||
// 二叉排序树T查找成功的平均查找长度
|
||||
double ASL(Tree *root, int level) {
|
||||
if (root == NULL)
|
||||
return 0;
|
||||
return level + ASL(root->l, level + 1) + ASL(root->r, level + 1);
|
||||
}
|
||||
|
||||
// 找到二叉树中值为val的节点并删除
|
||||
void delNode(Tree *root, int val) {
|
||||
if (root == NULL)
|
||||
return;
|
||||
if (root->val == val) {
|
||||
if (root->l == NULL && root->r == NULL) {
|
||||
if (root->parent->l == root) {
|
||||
root->parent->l = NULL;
|
||||
} else {
|
||||
root->parent->r = NULL;
|
||||
}
|
||||
free(root);
|
||||
} else if (root->l == NULL) {
|
||||
if (root->parent->l == root) {
|
||||
root->parent->l = root->r;
|
||||
} else {
|
||||
root->parent->r = root->r;
|
||||
}
|
||||
free(root);
|
||||
} else if (root->r == NULL) {
|
||||
if (root->parent->l == root) {
|
||||
root->parent->l = root->l;
|
||||
} else {
|
||||
root->parent->r = root->l;
|
||||
}
|
||||
free(root);
|
||||
} else {
|
||||
Tree *p = root->r;
|
||||
while (p->l != NULL) {
|
||||
p = p->l;
|
||||
}
|
||||
root->val = p->val;
|
||||
delNode(p, p->val);
|
||||
}
|
||||
} else if (root->val > val) {
|
||||
delNode(root->l, val);
|
||||
} else {
|
||||
delNode(root->r, val);
|
||||
}
|
||||
}
|
||||
|
||||
void detail(Tree *root) {
|
||||
if (root == NULL)
|
||||
return;
|
||||
printf("val: %d, height: %d, balance: %d, parent: %d\n", root->val,
|
||||
root->height, root->balance,
|
||||
root->parent == NULL ? -1 : root->parent->val);
|
||||
detail(root->l);
|
||||
detail(root->r);
|
||||
}
|
||||
|
||||
void pt(Tree *root) {
|
||||
printf("inOrder:\n");
|
||||
inOrder(root);
|
||||
printf("\n");
|
||||
detail(root);
|
||||
printf("ASL: %lf\n", ASL(root, 1) / n);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main() {
|
||||
freopen("data.in", "r", stdin);
|
||||
scanf("%d", &n);
|
||||
Tree *root = NULL;
|
||||
for (int i = 0; i < n; i++) {
|
||||
int val;
|
||||
scanf("%d", &val);
|
||||
root = insertNode(root, val);
|
||||
}
|
||||
pt(root);
|
||||
|
||||
scanf("%d", &m);
|
||||
for (int i = 0; i < m; i++) {
|
||||
int x;
|
||||
scanf("%d", &x);
|
||||
root = deleteNode(root, x);
|
||||
pt(root);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Binary file not shown.
Loading…
Reference in New Issue