声明:
这篇是转载的。
删除节点建议懒删除。
节点的旋转细节讲解参看原贴。
出处:https://www.cnblogs.com/skywang12345/p/3576969.html
原贴写的非常好,致敬!
直接上代码
#include <stdio.h>
#include <stdlib.h>
/**
* AVL平衡树
* 2019-09-27
*/
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MAX_QUEUE_SIZE 50
typedef int ElementType;
typedef struct Node{
ElementType data;
struct Node *left, *right;
int height; //节点高度
}Node, *AVLTree;
typedef struct {
AVLTree queue[MAX_QUEUE_SIZE];
int front;
int rear;
}Queue,*QueuePtr;
/**
* 获取树的高度
* @param T
* @return
*/
int getHeight(AVLTree T)
{
if(NULL == T)
return 0;
int lh = getHeight(T->left);
int rh = getHeight(T->right);
int max = MAX(lh, rh);
return max + 1;
}
/**
* 左单旋转
* @param k2 失去平衡的结点
* @return 旋转后的根结点
*/
Node *llRotation(AVLTree k2)
{
AVLTree k1;
k1 = k2->left;
k2->left = k1->right;
k1->right = k2;
k2->height = MAX(getHeight(k2->left), getHeight(k2->right));
k1->height = MAX(getHeight(k1->left), getHeight(k1->right));
return k1;
}
/**
* 右单旋
* @param k1 失去平衡的结点
* @return 旋转后的根结点
*/
Node *rrRotation(AVLTree k1)
{
AVLTree k2;
k2 = k1->right;
k1->right = k2->left;
k2->left = k1;
k1->height = MAX(getHeight(k1->left), getHeight(k1->right));
k2->height = MAX(getHeight(k2->left), getHeight(k2->right));
return k2;
}
/**
* LR 左双旋转
* @param k3 失去平衡的结点
* @return 旋转后的根节点
*/
Node *lrRotation(AVLTree k3)
{
k3->left = rrRotation(k3->left);
return llRotation(k3);
}
/**
* RL 右双旋转
* @param k1 失去平衡的结点
* @return 旋转后的根节点
*/
Node *rlRotation(AVLTree k1)
{
k1->right = llRotation(k1->right);
return rrRotation(k1);
}
/**
* 将结点插入AVL树中,并返回根结点
* @param T 根结点
* @param key
* @return
*/
Node * insert(AVLTree T, ElementType key)
{
if(NULL == T)
{
T = (Node *)malloc(sizeof(Node));
if(!T)
{
printf("Memory allocated to node Failure!\n");
exit(-1);
}
T->data = key;
T->left = NULL;
T->right = NULL;
T->height = 1;
}
else if(key < T->data)
{
T->left = insert(T->left, key);
//插入结点后,若AVL树失去平衡,则进行相应的调节
if(getHeight(T->left) - getHeight(T->right) ==2)
{
if(key < T->left->data)
T = llRotation(T);
else
T = lrRotation(T);
}
}
else if(key > T->data)
{
T->right = insert(T->right, key);
if(getHeight(T->right) - getHeight(T->left) ==2)
{
if(key > T->right->data)
T = rrRotation(T);
else
T = rlRotation(T);
}
}
else
{
printf("添加失败:不允许添加相同的结点!\n");
}
T->height = MAX(getHeight(T->left), getHeight(T->right));
return T;
}
/**
* 层遍历树
* @param T
*/
void levelOrderTraverse(AVLTree T)
{
if(NULL == T)
{
printf("Tree is Empty!\n");
return;
}
QueuePtr Q = (QueuePtr)malloc(sizeof(Queue));
if(!Q)
{
printf("Memory allocate to queue failed!\n");
exit(-1);
}
AVLTree temp;
//1.初始化,树根节点入队
Q->front =0;
Q->rear =0;
Q->queue[Q->rear++] = T;
//2.队列不为空
while(Q->front != Q->rear)
{
temp = Q->queue[(Q->front++)%MAX_QUEUE_SIZE];
printf("%d ", temp->data);
if(temp->left)
{
if((Q->rear+1)%MAX_QUEUE_SIZE == Q->rear)
{
printf("队列满!\n");
exit(-1);
}
Q->queue[(Q->rear++)%MAX_QUEUE_SIZE] = temp->left;
}
if(temp->right)
{
if((Q->rear+1)%MAX_QUEUE_SIZE == Q->rear)
{
printf("队列满!\n");
exit(-1);
}
Q->queue[(Q->rear++)%MAX_QUEUE_SIZE] = temp->right;
}
}
}
int main() {
/**
* 测试1- 3,2,1,4,5,6,7,16,15,14,13,12,11,10,8,9
* 测试2- 88,70,61,96,120,90,65
*/
int arr[] = {3,2,1,4,5,6,7,16,15,14,13,12,11,10,8,9};
AVLTree root = NULL;
int length = sizeof(arr)/ sizeof(arr[0]);
printf("依次添加: ");
for(int i=0; i<length; i++)
{
printf("%d ", arr[i]);
root = insert(root, arr[i]);
}
printf("\n层遍历树: ");
levelOrderTraverse(root);
printf("\n");
int height = getHeight(root);
printf("树的高度: %d.\n", height);
printf("done!\n");
return 0;
}