cpp
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<iostream>
#include <stack>
using namespace std;
typedef int ELEMTYPE;
typedef struct AVLNode{
ELEMTYPE val;
struct AVLNode* leftchild;
struct AVLNode* rightchild;
//用递归实现 双亲就不需要了
int height;//节点的高度 防止bst退化
}AVLNode;
//辅助节点
typedef struct AVLTree{
AVLNode* root;
}AVLTree;
//1.购买新节点
AVLNode* BuyNode(int val) {
AVLNode* p = (AVLNode*)malloc(sizeof(AVLNode));
if (p == nullptr) {
cout << "init err" << endl;
return nullptr;
}
p->height = 0;
p->leftchild = p->rightchild = 0;
p->val = val;
return p;
}
//2.获取当前节点的高度
int Get_Height(AVLNode* Node) {
if (Node == nullptr)return -1;
return Node->height;
}
//3.更新当前节点的高度
void Update_Height(AVLNode* Node) {
assert(Node != nullptr);
int lh = Get_Height(Node->leftchild);
int rh = Get_Height(Node->rightchild);
Node->height = lh > rh ? lh + 1 : rh + 1;
}
//4.获取当前节点的平衡因子
int Get_BalanceFactor(AVLNode* Node) {
assert(Node != nullptr);
if (Node == nullptr)return 0;
int lh = Get_Height(Node->leftchild);
int rh = Get_Height(Node->rightchild);
return lh - rh;
}
//5.左旋 将冲突节点旋转到自己右孩子的左边
// 要是右孩子左边有节点了就存一下那个节点先把冲突节点安置好再插回去
AVLNode* Left_Rotate(AVLNode* node) {
assert(node != nullptr);
AVLNode* child = node->rightchild;
AVLNode* temp = child->leftchild;
child->leftchild = node;
node->rightchild = temp;
Update_Height(node);
Update_Height(child);
return child;
}
//6.右旋 将冲突节点旋转到自己左孩子的右边
// 要是左孩子右边有节点了就存一下那个节点先把冲突节点安置好再插回去
AVLNode* Right_Rotate(AVLNode* node) {
assert(node != nullptr);
AVLNode* child = node->leftchild;
AVLNode* temp = child->rightchild;
child->rightchild = node;
node->leftchild = temp;
Update_Height(node);
Update_Height(child);
return child;
}
//7.通用的旋转函数(接收接收node,对node进行判断,如果没有
// 失衡,则不用调整最直接退出,反之如果失衡,则调整好再退出)
AVLNode* Rotate(AVLNode* node) {
assert(node != nullptr);
int ba = Get_BalanceFactor(node);
if (ba == 2){//L 如果失衡 那么一定是2/-2
//2.再用一个变量,用来保存node节点的左孩子的平衡因子
int ba_leftchild = Get_BalanceFactor(node->leftchild);
if (ba_leftchild == 1 || ba_leftchild == 0){//LL型
return Right_Rotate(node);
}
if (ba_leftchild == -1){//LR
//先左旋 //是对失衡节点的左孩子说的
node->leftchild = Left_Rotate(node->leftchild);
//再右旋 //是对失衡节点自身说的
return Right_Rotate(node);
}
}
if (ba == -2){//R
//3..再用一个变量,用来保存node节点的右孩子的平衡因子
int ba_rightchild = Get_BalanceFactor(node->rightchild);
if (ba_rightchild == -1 || ba_rightchild == 0){//RR
//单左旋完成
return Left_Rotate(node);
}
if (ba_rightchild == 1){//RL
//先右旋 //是对失衡节点的右孩子说的
node->rightchild = Right_Rotate(node->rightchild);
//再左旋 //是对失衡节点自身说的
return Left_Rotate(node);
}
}
return node;
}
//普通函数
//1.初始化
void Init_AVLTree(AVLTree* pTree) {
assert(pTree != nullptr);
pTree->root = nullptr;
}
//2.插入(启动函数)
bool Insert_AVL(AVLTree* pTree, ELEMTYPE val) {
assert(pTree != nullptr);
pTree->root = Insert_Helper(pTree->root, val);
return true;
}
//2.5 插入函数的递归函数
AVLNode* Insert_Helper(AVLNode* root, ELEMTYPE val) {
if (root == nullptr){
AVLNode* pnewnode = BuyNode(val);
return pnewnode;
}
//判断当前root指向的节点的数据域 是等于val/大于val/小于val
if (val == root->val){
return root;
}
if (val < root->val){
root->leftchild = Insert_Helper(root->leftchild, val);
}
else{
root->rightchild = Insert_Helper(root->rightchild, val);
}
Update_Height(root);
root = Rotate(root);//Rotate 去修root修复 从上至下
return root;
}
//3.删除(启动函数)
bool Delete_AVL(AVLTree* pTree, ELEMTYPE val) {
assert(pTree != nullptr);
pTree->root = Delete_Helper(pTree->root, val);
return true;
}
//3.5 删除函数的递归函数
AVLNode* Delete_Helper(AVLNode* root, ELEMTYPE val) {
if (root == nullptr)return nullptr;
if (val < root->val){
root->leftchild = Delete_Helper(root->leftchild, val);
}
else if (val > root->val){
root->leftchild = Delete_Helper(root->rightchild, val);
}
else{//找到了
AVLNode* temp = root;
AVLNode* child = nullptr;
//是双分支情况
if (root->leftchild && root->rightchild ){
temp = temp->rightchild;
while (temp->leftchild) temp = temp->leftchild;
root->val = temp->val;
root->rightchild = Delete_Helper(root->rightchild, temp->val);
}
else{
//无叶子节点
if (root->leftchild)//只有左孩子
child = temp->leftchild;
else //只有右孩子/无孩子(child=nullptr
child = temp->rightchild;
free(root);
return child;
}
}
//更新当前节点
Update_Height(root);
//再将此时的root扔到通用旋转函数里,出来后肯定是平衡的,直接返回即可
return Rotate(root);
}
//4.查找
AVLNode* Search_AVL(AVLNode* root, ELEMTYPE val) {
if (root == nullptr)return nullptr;
AVLNode* temp = root;
while (temp) {
if (val > temp->val)temp = temp->rightchild;
else if (val < temp->val)temp = temp->leftchild;
else return temp;
}return nullptr;
}
//5.打印 中序遍历
void Show_InOrder(AVLNode* root) {
assert(root != nullptr);
AVLNode* temp = root;
stack<AVLNode*>st1;
while (!st1.empty() || temp) {
while (temp) {
st1.push(temp);
temp = temp->leftchild;
}
temp = st1.top();
st1.pop();
cout << temp->val << " ";
temp = temp->rightchild;
}
cout << endl;
}
int main() {
return 0;
}
理解左旋右旋那些点之后就不难了qvq
