//LL型失衡 右旋
//RR型失衡 左旋
//RL型失衡 先右旋 再左旋
//LR型失衡 先左旋 再右旋
#include "stdio.h"
#include "stdlib.h"
typedef int ElemType;
typedef struct node {
ElemType data;
int height;
struct node *left;
struct node *right;
} Node;
Node *create_node(ElemType value) {
Node *node = (Node *) malloc(sizeof(Node));
if (node == NULL) {
exit(-1);
}
node->data = value;
node->height = 1;
node->left = NULL;
node->right = NULL;
return node;
}
//获取树的高度
int getHeight(Node *node) {
if (node == NULL) {
return 0;
}
return node->height;
}
int max(int a, int b) {
return a > b ? a : b;
}
int getTreeHeight(Node *node) {
if (node == NULL) {
return 0;
}
return max(getTreeHeight(node->left), getTreeHeight(node->right)) + 1;
}
//左旋转
Node *leftRotate(Node *root) {
Node *newroot = root->right;//当前结点的右子节点作为新的树根
root->right = newroot->left;//将新树根的左子树作为原根的右子树
newroot->left = root;//将原根作为新根的左子树
root->height = 1 + max(getHeight(root->left), getHeight(root->right));
newroot->height = 1 + max(getHeight(newroot->left), getHeight(newroot->right));
return newroot;
}
//右旋转
Node *rightRotate(Node *root) {
Node *newroot = root->left;//当前结点的左节点作为新的树根
root->left = newroot->right;//将新节点右边的子树作为原根结点的左子树
newroot->right = root;//新节点的右子树为原根结点
root->height = 1 + max(getHeight(root->left), getHeight(root->right));
newroot->height = 1 + max(getHeight(newroot->left), getHeight(newroot->right));
return newroot;
}
//获取平衡因子
int getBalance(Node *node) {
return getHeight(node->left) - getHeight(node->right);
}
//插入
Node *insert_node(Node *node, ElemType value) {
if (node == NULL) {
return create_node(value);
}
if (node->data > value) {
node->left = insert_node(node->left, value);
} else if (node->data < value) {
node->right = insert_node(node->right, value);
} else {
return node;
}
//更新树高
node->height = 1 + max(getHeight(node->left), getHeight(node->right));
// 获取平衡因子
int balance = getBalance(node);
//LL型失衡
if (balance > 1 && getBalance(node->left) > 0) {
return rightRotate(node);
}
//LR型失衡
if (balance > 1 && getBalance(node->left) < 0) {
node->left = leftRotate(node->left);
return rightRotate(node);
}
//RR型失衡
if (balance < -1 && getBalance(node->right) < 0) {
return leftRotate(node);
}
//RL型失衡
if (balance < -1 && getBalance(node->right) > 0) {
node->right = rightRotate(node->right);
return leftRotate(node);
}
return node;
}
void preOrder(Node *node) {
if (node == NULL) {
return;
}
printf("%d ", node->data);
preOrder(node->left);
preOrder(node->right);
}
void inOrder(Node *node) {
if (node == NULL) {
return;
}
inOrder(node->left);
printf("%d ", node->data);
inOrder(node->right);
}
Node *find(Node *node, ElemType value, int *counter) {
Node *current = node;
while (current != NULL) {
if (current->data > value) {
current = current->left;
(*counter)++;
} else if (current->data < value) {
current = current->right;
(*counter)++;
} else {
(*counter)++;
return current;
}
}
return NULL;
}
//删除节点恢复平衡
/*
* 前半部分 二叉搜索树的删除
* 后半部分 插入节点导致失衡的修改,稍作调整
* */
Node *delete_node(Node *node, int value) {
if (node == NULL) {
return NULL;
}
if (node->data > value) {
node->left = delete_node(node->left, value);
} else if (node->data < value) {
node->right = delete_node(node->right, value);
} else if (node->data == value) {
//情况一 要删除的节点就是叶子结点
if (node->left == NULL && node->right == NULL) {
Node *temp = node;
node = NULL;
free(temp);
} else if (node->left == NULL && node->right != NULL) {
//情况二 只有一个方向有节点 直接用有节点的数据进行替换就可以了
Node *temp = node;
node = node->right;
free(temp);
} else if (node->left != NULL && node->right == NULL) {
//情况二 只有一个方向有节点
Node *temp = node;
node = node->left;
free(temp);
} else if (node->left != NULL && node->right != NULL) {
//情况三 要删除的节点有左孩子也有右孩子
Node *current = node->right;
while (current->left != NULL) {
current = current->left;
}
node->data = current->data;
node->right = delete_node(node->right, current->data);
}
}
//删除完成 下面开始调整
if (node == NULL) {
return node;
}
//更新树高
node->height = 1 + max(getHeight(node->left), getHeight(node->right));
// 获取平衡因子
int balance = getBalance(node);
//LL型失衡
if (balance > 1 && getBalance(node->left) >= 0) {
return rightRotate(node);
}
//LR型失衡
if (balance > 1 && getBalance(node->left) < 0) {
node->left = leftRotate(node->left);
return rightRotate(node);
}
//RR型失衡
if (balance < -1 && getBalance(node->right) <= 0) {
return leftRotate(node);
}
//RL型失衡
if (balance < -1 && getBalance(node->right) > 0) {
node->right = rightRotate(node->right);
return leftRotate(node);
}
return node;
}
void test() {
Node *root = insert_node(NULL, 1);
root = insert_node(root, 2);
root = insert_node(root, 3);
root = insert_node(root, 4);
root = insert_node(root, 5);
root = insert_node(root, 6);
root = insert_node(root, 7);
root = insert_node(root, 8);
root = insert_node(root, 9);
root = insert_node(root, 10);
int counter = 0;
Node *result = find(root, 6, &counter);
if (result) {
printf("找了%d次", counter);
}
printf("\n前序遍历\n");
preOrder(root);
printf("\n中序遍历\n");
inOrder(root);
// root = delete_node(root, 1);
// root = delete_node(root, 2);
// root = delete_node(root, 7);
// printf("\n前序遍历\n");
// preOrder(root);
// printf("\n中序遍历\n");
// inOrder(root);
printf("\n树高为%d", getTreeHeight(root));
}
int main() {
test();
return 0;
}
运行效果