题意:给你很多单词,统计每个单词出现的频率。。。
分析:题目没什么说的。。
对AVL树,是对BST的进行了平衡处理,保证任何一棵子树深度差值不超过1.。。使得在任意情况下不会退化到O(n^2)。。。
当出现不平衡时找到最靠近插入点的左右子树相差超过1的根节点
共分四种情况:
1.左子树比右子树深超过1(只进行右旋R 或 先左旋后右旋LR)
2.右子树比左子树深超过1(只进行左旋L 或 先右旋后左旋RL)
第一次写,wa得泪流满面。。
代码:
#include<iostream>
using namespace std;
const int N=100010;
int n, cnt, num, root, taller;
char s[35];
struct node
{
char s[36];
int cnt, bs, lchild, rchild;
void init()
{
cnt = 1;
bs = 0;
lchild = rchild = -1;
}
} a[N];
void r_rotate(int &p) //右旋
{
int lc = a[p].lchild;
a[p].lchild = a[lc].rchild;
a[lc].rchild = p;
p = lc;
}
void l_rotate(int &p) //左旋
{
int rc = a[p].rchild;
a[p].rchild = a[rc].lchild;
a[rc].lchild = p;
p = rc;
}
void l_balance(int &p) //对左子树引起的不平衡进行恢复
{
int lc, rc;
lc = a[p].lchild;
if(a[lc].bs==1)
{
a[p].bs = a[lc].bs = 0;//需在旋转前面改变。。也wa了好久
r_rotate(p);
}
else
{
rc = a[lc].rchild;
if(a[rc].bs==0)//初次加入该点时出现的情况。。
a[p].bs = a[lc].bs = 0;
else if(a[rc].bs==1)
a[lc].bs = 0, a[p].bs = -1;
else
a[lc].bs = 1, a[p].bs = 0;
a[rc].bs = 0;
l_rotate(a[p].lchild);
r_rotate(p);
}
}
void r_balance(int &p)//对右子树引起的不平衡进行恢复
{
int lc, rc;
rc = a[p].rchild;
if(a[rc].bs==-1)
{
a[p].bs = a[rc].bs = 0;
l_rotate(p);
}
else
{
lc = a[rc].lchild;
if(a[lc].bs==0)
a[p].bs = a[rc].bs = 0;
else if(a[lc].bs==1)
a[p].bs = 0, a[rc].bs = -1;
else
a[p].bs = 1, a[rc].bs = 0;
a[lc].bs = 0;
r_rotate(a[p].rchild);
l_rotate(p);
}
}
void insert(int &p) //插入节点
{
if(p==-1)
{
p = cnt++;
a[p].init();
strcpy(a[p].s, s);
taller = 1;
return;
}
int cmp=strcmp(s, a[p].s);
if(cmp==0)
{
//taller = 0;//想不懂为什么非要加这一句啊。。。》添加第一个节点时taller变1了。。每次插入前将taller请0就好了。。
a[p].cnt++;
}
else if(cmp<0)
{
insert(a[p].lchild);
if(taller)
{
if(a[p].bs==1)
{
l_balance(p);
taller = 0;
}
else
{
a[p].bs++;
if(a[p].bs!=0)
taller = 1;
else
taller = 0;
}
}
}
else
{
insert(a[p].rchild);
if(taller)
{
if(a[p].bs==-1)
{
r_balance(p);
taller = 0;
}
else
{
a[p].bs--;
if(a[p].bs!=0)
taller = 1;
else
taller = 0;
}
}
}
}
void dfs(int p) //遍历整棵树
{
if(p==-1)
return;
dfs(a[p].lchild);
printf("%s %.4lf\n", a[p].s, (double)a[p].cnt*100/num);
dfs(a[p].rchild);
}
int main()
{
cnt = num = taller = 0;
root = -1;
while(gets(s))
{
taller = 0;
insert(root);
num++;
}
dfs(root);
return 0;
}