Problem Description
根据给定的输入序列建立一棵平衡二叉树,求出建立的平衡二叉树的树根。
Input
输入一组测试数据。数据的第1行给出一个正整数N(n <= 20),N表示输入序列的元素个数;第2行给出N个正整数,按数据给定顺序建立平衡二叉树。
Output
输出平衡二叉树的树根。
Example Input
5
88 70 61 96 120
Example Output
70
先贴上学AVL树时参考的课本代码, 待会把自己改装过的代码贴上
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#define LH 1
#define RH -1
#define EH 0
using namespace std;
typedef int Elemtype;
typedef struct node
{
Elemtype data;
struct node *left;
struct node *right;
int bf;
} BSTNode, *BSTree;
void R_Rotate(BSTree &p)
{
BSTree lc;
lc = p -> left;
p -> left = lc -> right;
lc -> right = p;
p = lc;
}
void L_Rotate(BSTree &p)
{
BSTree rc = p -> right;
p -> right = rc -> left;
rc -> left = p;
p = rc;
}
void LeftBalance(BSTree& root)
{
BSTree lc = root -> left;
BSTree rd;
switch(lc -> bf)
{
case LH:
lc -> bf = root -> bf = EH;
R_Rotate(root);
break;
case RH:
rd = lc -> right;
switch(rd -> bf)
{
case LH:
root -> bf = RH;
lc -> bf = EH;
break;
case EH:
root -> bf = lc -> bf = EH;
break;
case RH:
root -> bf = EH;
lc -> bf = LH;
break;
}
rd -> bf = EH;
L_Rotate(root -> left);
R_Rotate(root);
}
}
void RightBalance(BSTree &root)
{
BSTree rc = root -> right;
BSTree ld;
switch(rc -> bf)
{
case RH:
L_Rotate(root);
rc -> bf = root -> bf = EH;
break;
case LH:
{
ld = rc -> left;
switch(ld -> bf)
{
case LH:
root -> bf = EH;
rc -> bf = RH;
break;
case EH:
root -> bf = rc -> bf = EH;
case RH:
root -> bf = LH;
rc -> bf = EH;
}
}
ld -> bf = EH;
R_Rotate(root -> right);
L_Rotate(root);
}
}
bool InsertAVL(BSTree &root, Elemtype e, bool &taller)
{
if(!root)
{
root = (BSTree)malloc(sizeof(BSTNode));
root -> left = root -> right = NULL;
root -> bf = EH;
root -> data = e;
taller = true;
}
else
{
if(e == root -> data)
{
taller = false;
return 0;
}
if(e < root -> data)
{
if(!InsertAVL(root -> left, e, taller))
{
return 0;
}
if(taller)
{
switch(root -> bf)
{
case LH:
LeftBalance(root);
taller = false;
break;
case EH:
root -> bf = LH;
taller = true;
break;
case RH:
root -> bf = EH;
taller = false;
break;
}
}
}
else
{
if(!InsertAVL(root -> right, e, taller))
{
return 0;
}
if(taller)
{
switch(root -> bf)
{
case LH:
root -> bf = EH;
taller = false;
break;
case EH:
root -> bf = RH;
taller = true;
break;
case RH:
RightBalance(root);
taller = false;
break;
}
}
}
}
return true;
}
int main()
{
BSTree root = NULL;
int n;
while(cin >> n)
{
root = NULL;
Elemtype t;
for(int i = 0; i < n; i++)
{
bool flag = false;
scanf("%d", &t);
InsertAVL(root, t, flag);
}
printf("%d\n", root -> data);
}
return 0;
}
下面是我自己写的,去掉了一些关于平衡因子的操作,用树的深度来判断用哪个旋转。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#define LH 1
#define RH -1
#define EH 0
using namespace std;
typedef int Elemtype;
typedef struct node
{
Elemtype data;
struct node *left;
struct node *right;
int deep;//树的深度
} BSTNode, *BSTree;
int Deep(BSTree &root)//返回树的深度
{
if(!root)
return -1;
return root -> deep;
}
void R_Rotate(BSTree &p)//右单旋操作
{
BSTree lc = p -> left;
p -> left = lc -> right;
lc -> right = p;
lc -> deep = max(Deep(lc -> left), Deep(lc -> right)) + 1;
p -> deep = max(Deep(p -> left), Deep(p -> right)) + 1;
p = lc;
}
void L_Rotate(BSTree &p)//左单旋操作
{
BSTree rc = p -> right;
p -> right = rc -> left;
rc -> left = p;
p -> deep = max(Deep(p -> left), Deep(p -> right)) + 1;
rc -> deep = max(Deep(rc -> right), Deep(rc -> left)) + 1;
p = rc;
}
bool Insert(BSTree &root, Elemtype e)//插入节点e
{
if(!root)
{
root = new BSTNode;
root -> data = e;
root -> left = root -> right = NULL;
root -> deep = 0;
return true;
}
if(e == root -> data)
{
return false;//无需插入,返回false,可忽略此处操作
}
else if(e < root -> data)//插入左子树
{
Insert(root -> left, e);
if(Deep(root -> left) - Deep(root -> right) == 2)//不平衡
{
if(e < root -> left -> data)//判断右单旋条件
{
R_Rotate(root);
}
else//左右双旋
{
L_Rotate(root -> left);
R_Rotate(root);
}
}
}
else//插入右子树
{
Insert(root -> right, e);
if(Deep(root -> right) - Deep(root -> left) == 2)//判断不平衡
{
if(e < root -> right -> data)//判断右左双旋条件
{
R_Rotate(root -> right);
L_Rotate(root);
}
else//判断左单旋
{
L_Rotate(root);
}
}
}
root -> deep = max(Deep(root -> left), Deep(root -> right)) + 1;//更新深度值
return true;
}
int main()
{
int n;
while(cin >> n)
{
BSTree root = NULL;
for(int i = 0; i < n; i++)
{
int t;
scanf("%d", &t);
Insert(root, t);
}
printf("%d\n", root -> data);
}
return 0;
}