#include <iostream>
#include <deque>
class AVLTree
{
private:
struct Node
{
int data; //元素
Node * left = nullptr; //左孩子
Node * right = nullptr; //右孩子
int height = -1; //节点高度
Node(int data, int height) :data(data), height(height) {};
};
Node * root = nullptr; //根节点
bool internalPush(Node * & root, int value)
{
bool result = false; //操作结果
if (root == nullptr) //如果找到合适的位置 新建对象并且用当前指针指向它
{
root = new Node(value, 0);
result = true;
}
else if (root->data == value) //如果已经有改元素 结果为失败 不做处理
{
result = false;
}
else if (root->data > value)
{
result = internalPush(root->left, value); //在左子树中寻找合适的位置
if (nodeHeight(root->left) - nodeHeight(root->right) == 2) //判断当前节点是否失去平衡
{
if (root->left->data > value) //如果左子树的根节点的值大于插入值 表明是插入在左子树的左边
{
singleRight(root); //单次右旋
}
else
{
leftRight(root); //先左旋在右旋
}
}
}
else
{
result = internalPush(root->right, value);
if (nodeHeight(root->right) - nodeHeight(root->left) == 2)
{
if (root->right->data < value)
{
singleLeft(root);
}
else
{
rightLeft(root);
}
}
}
root->height = treeHeight(root->left, root->right); //更新节点高度
return result;
}
void singleRight(Node * & node)
{
Node * temp = node->left; //因为node的left要挂载left的right 所以需要先保存node的left 防止指针丢失
node->left = temp->right; //node的left指向 temp的right
temp->right = node;
node->height = treeHeight(node->left, node->right); //先计算当前右子树的高度
temp->height = treeHeight(temp->left, temp->right); //在计算子树的高度
node = temp; //将当前子树绑定整个AVL树
}
void singleLeft(Node *& node)
{
Node * temp = node->right;
node->right = temp->left;
temp->left = node;
node->height = treeHeight(node->left, node->right);
temp->height = treeHeight(temp->left, temp->right);
node = temp;
}
void leftRight(Node *& node)
{
singleLeft(node->left);
singleRight(node);
}
void rightLeft(Node *& node)
{
singleRight(node->right);
singleLeft(node);
}
int nodeHeight(Node * node)
{
return node == nullptr ? -1 : node->height;
}
int treeHeight(Node * left, Node * right)
{
return nodeHeight(left) > nodeHeight(right) ? nodeHeight(left) + 1 : nodeHeight(right) + 1;
}
bool internalRemove(Node *& root, int value)
{
bool result = false;
if (root == nullptr) //删除失败
{
result = false;
}
else if (root->data > value)
{
result = internalRemove(root->left, value);
if (nodeHeight(root->right) - nodeHeight(root->left) == 2)
{
// 通过树高比较 选择旋转类型
if (nodeHeight(root->right->right) > nodeHeight(root->right->left))
{
singleLeft(root);
}
else
{
rightLeft(root);
}
}
}
else if (root->data < value)
{
result = internalRemove(root->right, value);
if (nodeHeight(root->left) - nodeHeight(root->right) == 2)
{
if (nodeHeight(root->left->left) > nodeHeight(root->left->right))
{
singleRight(root);
}
else
{
leftRight(root);
}
}
}
else
{
if (root->left == nullptr && root->right == nullptr)
{
delete root;
root = nullptr;
result = true;
}
else if (root->left != nullptr && root->right == nullptr)
{
//将当前节点的左孩子赋值给自己 然后释放内存
Node * temp = root;
root = root->left;
delete temp;
result = true;
}
else if (root->right != nullptr && root->left == nullptr)
{
Node * temp = root;
root = root->right;
delete temp;
result = true;
}
else
{
//将左子树最小的值赋给它 然后删除右子树最小值
int miniValue = findMini(root->right);
root->data = miniValue;
result = internalRemove(root->right, miniValue);
if (nodeHeight(root->left) - nodeHeight(root->right) == 2)
{
if (nodeHeight(root->left->left) > nodeHeight(root->left ->right))
{
singleRight(root);
}
else
{
leftRight(root);
}
}
}
}
if (root != nullptr)
{
root->height = treeHeight(root->left, root->right);
}
return result;
}
int findMini(Node * node)
{
if (node == nullptr)
{
throw;
}
Node * pre = node;
while (node != nullptr)
{
pre = node;
node = node->left;
}
return pre->data;
}
public:
bool push(int value)
{
return internalPush(root, value);
}
bool remove(int value)
{
return internalRemove(root, value);
}
bool contains(int value)
{
Node * cursor = root;
while(cursor != nullptr)
{
if(cursor->data == value)
{
return true;
}
else if(cursor->data > value)
{
cursor = cursor->left;
}
else
{
cursor = cursor->right;
}
}
return false;
}
void floorTraversalPrint()
{
if (root != nullptr)
{
std::deque<Node *> q;
q.push_back(root);
while (!q.empty())
{
Node * temp = q.front();
std::cout << temp->data << std::ends;
if (temp->left != nullptr)
{
q.push_back(temp->left);
}
if (temp->right != nullptr)
{
q.push_back(temp->right);
}
q.pop_front();
}
}
}
};
int main(int args, char *argv[])
{
AVLTree tree;
tree.push(233);
tree.push(32);
tree.floorTraversalPrint();
std::cout << tree.contains(3332) ;
return 0;
}
Blue is white,dark is not blue(AVL树)
最新推荐文章于 2024-07-14 21:31:19 发布