这道题核心平衡树的代码在MOOC上有,需要完善修改即可。
机翻
1、条件准备
定义结构体,高度,值,左结点,右结点
cpp
复制代码
#include <iostream>
#include <stdlib.h>
using namespace std;
typedef struct AVLNode *position;
typedef position AVLTree;
typedef int ElementType;
struct AVLNode
{
ElementType data;
AVLTree Left;
AVLTree Right;
int height;
};
主函数读入结点,调用insert函数插入,最后输出根节点值
cpp
复制代码
int main()
{
int n;
cin >> n;
AVLTree T = NULL;
for (int i = 0; i < n; i++)
{
int a;
cin >> a;
T = insert(T, a);
}
cout << T->data;
return 0;
}
2、平衡树四种旋转
具体逻辑在MOOC的ppt上有讲述,如果对代码不太理解我建议举例子推一遍比较好
cpp
复制代码
AVLTree singleleftrotation(AVLTree A)
{
//左左
AVLTree B = A->Left;
A->Left = B->Right;
B->Right = A;
A->height = max(getheight(A->Left), getheight(A->Right)) + 1;
B->height = max(getheight(B->Left), A->height) + 1;
return B;
}
AVLTree singlerightrotation(AVLTree A)
{
//右右
AVLTree B = A->Right;
A->Right = B->Left;
B->Left = A;
A->height = max(getheight(A->Left), getheight(A->Right)) + 1;
B->height = max(getheight(B->Right), A->height) + 1;
return B;
}
AVLTree doubleleftrotation(AVLTree A)
{
//左右
A->Left = singlerightrotation(A->Left);
return singleleftrotation(A);
}
AVLTree doublerightrotation(AVLTree A)
{
//右左
A->Right = singleleftrotation(A->Right);
return singlerightrotation(A);
}
3、getheight函数
获取树高度,递归实现
cpp
复制代码
int getheight(AVLTree A)
{
if (!A)
return 0;
return max(getheight(A->Left), getheight(A->Right)) + 1;
}
4、insert函数
跟MOOC上代码逻辑基本一样。
cpp
复制代码
AVLTree insert(AVLTree T, ElementType x)
{
if (!T)
{
AVLTree T = (AVLTree)malloc(sizeof(struct AVLNode));
T->data = x;
T->Right = T->Left = NULL;
return T;
}
else if (x < T->data)
{
T->Left = insert(T->Left, x);
if (getheight(T->Left) - getheight(T->Right) == 2)
{
if (x < T->Left->data)
T = singleleftrotation(T);
else
T = doubleleftrotation(T);
}
}
else if (x > T->data)
{
T->Right = insert(T->Right, x);
if (getheight(T->Right) - getheight(T->Left) == 2)
{
if (x > T->Right->data)
T = singlerightrotation(T);
else
T = doublerightrotation(T);
}
}
T->height = max(getheight(T->Left), getheight(T->Right)) + 1;
return T;
}
5、总结
这个题最难的在于平衡树代码和插入代码的实现,不过MOOC上也写出了不少,所以难度不算大。
完整代码如下:
cpp
复制代码
#include <iostream>
#include <stdlib.h>
using namespace std;
typedef struct AVLNode *position;
typedef position AVLTree;
typedef int ElementType;
struct AVLNode
{
ElementType data;
AVLTree Left;
AVLTree Right;
int height;
};
int getheight(AVLTree A)
{
if (!A)
return 0;
return max(getheight(A->Left), getheight(A->Right)) + 1;
}
AVLTree singleleftrotation(AVLTree A)
{
AVLTree B = A->Left;
A->Left = B->Right;
B->Right = A;
A->height = max(getheight(A->Left), getheight(A->Right)) + 1;
B->height = max(getheight(B->Left), A->height) + 1;
return B;
}
AVLTree singlerightrotation(AVLTree A)
{
AVLTree B = A->Right;
A->Right = B->Left;
B->Left = A;
A->height = max(getheight(A->Left), getheight(A->Right)) + 1;
B->height = max(getheight(B->Right), A->height) + 1;
return B;
}
AVLTree doubleleftrotation(AVLTree A)
{
A->Left = singlerightrotation(A->Left);
return singleleftrotation(A);
}
AVLTree doublerightrotation(AVLTree A)
{
A->Right = singleleftrotation(A->Right);
return singlerightrotation(A);
}
AVLTree insert(AVLTree T, ElementType x)
{
if (!T)
{
AVLTree T = (AVLTree)malloc(sizeof(struct AVLNode));
T->data = x;
T->Right = T->Left = NULL;
return T;
}
else if (x < T->data)
{
T->Left = insert(T->Left, x);
if (getheight(T->Left) - getheight(T->Right) == 2)
{
if (x < T->Left->data)
T = singleleftrotation(T);
else
T = doubleleftrotation(T);
}
}
else if (x > T->data)
{
T->Right = insert(T->Right, x);
if (getheight(T->Right) - getheight(T->Left) == 2)
{
if (x > T->Right->data)
T = singlerightrotation(T);
else
T = doublerightrotation(T);
}
}
T->height = max(getheight(T->Left), getheight(T->Right)) + 1;
return T;
}
int main()
{
int n;
cin >> n;
AVLTree T = NULL;
for (int i = 0; i < n; i++)
{
int a;
cin >> a;
T = insert(T, a);
}
cout << T->data;
return 0;
}