更新平衡
This commit is contained in:
parent
dda94299d0
commit
7cf9e6665f
|
@ -3,3 +3,4 @@
|
||||||
template/*
|
template/*
|
||||||
*.zip
|
*.zip
|
||||||
*/datas/*
|
*/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