#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef int DataType;
typedef struct SearchTree
{
int height;
DataType value;
struct SearchTree* left;
struct SearchTree* right;
} TreeNode, SearchTree;
TreeNode* SingleRotateWithLeft(TreeNode* grandpa);
TreeNode* SingleRotateWithRight(TreeNode* grandpa);
TreeNode* DoubleRotateWithLeft(TreeNode* grandpa);
TreeNode* DoubleRotateWithRight(TreeNode* grandpa);
TreeNode* Remove(SearchTree* tree, TreeNode* node);
void Assign(TreeNode* dest, DataType* value);
TreeNode* Find(SearchTree* tree, DataType value);
int getHeight(SearchTree* tree);
TreeNode* findExtreamNode(TreeNode* node);
void output(SearchTree* tree);
TreeNode* SingleRotateWithLeft(TreeNode* grandpa)
{
TreeNode* parent = grandpa->left;
grandpa->left = parent->right;
parent->right = grandpa;
grandpa->height = max(getHeight(grandpa->left), getHeight(grandpa->right)) + 1;
parent->height = max(getHeight(parent->left), grandpa->height) + 1;
return parent;
}
TreeNode* SingleRotateWithRight(TreeNode* grandpa)
{
TreeNode* parent = grandpa->right;
grandpa->right = parent->left;
parent->left = grandpa;
grandpa->height = max(getHeight(grandpa->left), getHeight(grandpa->right)) + 1;
parent->height = max(getHeight(parent->right), grandpa->height) + 1;
return parent;
}
TreeNode* DoubleRotateWithLeft(TreeNode* grandpa)
{
grandpa->left = SingleRotateWithRight(grandpa->left);
return SingleRotateWithLeft(grandpa);
}
TreeNode* DoubleRotateWithRight(TreeNode* grandpa)
{
grandpa->right = SingleRotateWithLeft(grandpa->right);
return SingleRotateWithRight(grandpa);
}
TreeNode* Insert(SearchTree* tree, DataType value)
{
if (tree == NULL)
{
TreeNode* temp = (TreeNode*)malloc(sizeof(TreeNode));
if (!temp)
{
return NULL;
}
temp->left = temp->right = NULL;
temp->value = value;
temp->height = 0;
return temp;
}
if (value < tree->value)
{
tree->left = Insert(tree->left, value);
if (getHeight(tree->left) - getHeight(tree->right) == 2)
{
if (value < tree->left->value)
tree = SingleRotateWithLeft(tree);
else
tree = DoubleRotateWithLeft(tree);
}
}
else if (value > tree->value)
{
tree->right = Insert(tree->right, value);
if (getHeight(tree->right) - getHeight(tree->left) == 2)
{
if (value > tree->right->value)
tree = SingleRotateWithRight(tree);
else
tree = DoubleRotateWithRight(tree);
}
}
else
return NULL;
tree->height = max(getHeight(tree-> left), getHeight(tree->right)) + 1;
return tree;
}
TreeNode* Remove(SearchTree* tree, TreeNode* node)
{
if (!tree || !node)
return NULL;
if (node == tree)
{
if (tree->left && tree->right)
{
TreeNode* leaf = findExtreamNode(tree);
bool doesLeft = true;
if (leaf->value > tree->value)
doesLeft = false;
Assign(tree, leaf->value);
if (doesLeft)
tree->left = Remove(tree->left, leaf);
else
tree->right = Remove(tree->right, leaf);
tree->height = max(getHeight(tree->left), getHeight(tree->right)) + 1;
return tree;
}
else if (!tree->left && !tree->right)
{
free(tree);
return NULL;
}
else if (tree->left || tree->right)
{
TreeNode* temp = tree->left ? tree->left : tree->right;
free(tree);
return temp;
}
}
else if(node->value > tree->value)
{
tree->right = Remove(tree->right, node);
if (abs(getHeight(tree->left) - getHeight(tree->right)) == 2)
tree = tree->left->left ? SingleRotateWithLeft(tree) : DoubleRotateWithLeft(tree);
}
else
{
tree->left = Remove(tree->left, node);
if (abs(getHeight(tree->left) - getHeight(tree->right)) == 2)
tree = tree->right->right ? SingleRotateWithRight(tree) : DoubleRotateWithRight(tree);
}
tree->height = max(getHeight(tree->left), getHeight(tree->right)) + 1;
return tree;
}
void Assign(TreeNode* dest, DataType* value)
{
dest->value = value;
}
TreeNode* Find(SearchTree* tree, DataType value)
{
TreeNode* cur = tree;
while (cur != NULL)
{
if (cur->value == value)
break;
cur = value > cur->value ? cur->right : cur->left;
}
return cur;
}
int getHeight(SearchTree* tree)
{
return tree ? tree->height : -1;
}
TreeNode* findExtreamNode(TreeNode* node)
{
if (node->right->height > node->left->height)
{
TreeNode* cur = node->right;
while (cur->left)
cur = cur->left;
return cur;
}
else
{
TreeNode* cur = node->left;
while (cur->right)
{
cur = cur->right;
}
return cur;
}
}
void output(SearchTree* tree)
{
if (!tree) return;
output(tree->left);
printf("value = %d, height = %d\n", tree->value, tree->height);
output(tree->right);
}
int main()
{
SearchTree* tree = NULL;
for (int i = 1; i <= 8; i++)
tree = Insert(tree, i);
tree = Remove(tree, Find(tree, 6));
output(tree);
system("pause");
}