poj2418 Hardwood Species

题目意思:美国有很多种类的树,有硬木的,有软木的,现在输入一堆树,根据树名的字典序,从小到大输出树名及它占所有树种的比例

这题可以用很多方法解,目前只用了AVL搜索树这种方法,就是AVL搜索树的一个套用

提醒一句,貌似好多人用g++交就是错的,c++交就是对的

代码如下:

#include<iostream>
#include<cstdlib>
#include<ctime>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
typedef struct AVLTree{
  char nData[132];
  double Count;
  int nHeight;
  struct AVLTree* pLeft;
  struct AVLTree* pRight;
}AVLTree;
int max(int a,int b);
int Height(AVLTree* pNode);
AVLTree* Insert(char *nData,AVLTree *pNode);
AVLTree* LLRotate(AVLTree* pNode);
AVLTree* RRRotate(AVLTree* pNode);
AVLTree* LRRotate(AVLTree* pNode);
AVLTree* RLRotate(AVLTree* pNode);
void DeleteTree(AVLTree** ppRoot);
void PrintTree(AVLTree* pRoot,double sum);
int Find(char *nData,AVLTree *pNode);

int main()
{
    //freopen("in.txt","r",stdin);
    char s[31];
    double sum = 0;
    AVLTree* pRoot = NULL;
    while (gets(s)){
        if (Find(s,pRoot) == 0)
        pRoot = Insert(s,pRoot);
        sum++;
    }
    PrintTree(pRoot,sum);
    //fclose(stdin);
    return 0;
}

int max(int a,int b)
{
    return (a<b?b:a);
}

int Height(AVLTree* pNode)
{
    if (pNode == NULL) return -1;
    return pNode->nHeight;
}

int Find(char *nData,AVLTree *pNode)
{
    if (pNode == NULL) return 0;
    if (strcmp(nData,pNode -> nData) == 0)
    {
        pNode -> Count++;
        return 1;
    }
    else if (strcmp(nData,pNode -> nData) < 0) return (Find(nData,pNode -> pLeft));
    else return (Find(nData,pNode -> pRight));
}

AVLTree* Insert(char *nData,AVLTree *pNode)
{
    if (pNode == NULL){
        pNode = (AVLTree* )malloc(sizeof(AVLTree));
        strcpy(pNode->nData,nData);
        pNode->nHeight = 0;
        pNode->Count = 1;
        pNode->pLeft = pNode->pRight = NULL;
    } else if ( strcmp(nData,pNode->nData) < 0 )//插入到左子树中去
    {
        pNode -> pLeft = Insert(nData, pNode -> pLeft);
        if ( Height(pNode -> pLeft) - Height(pNode -> pRight) == 2)
        {
            if (strcmp(nData,pNode -> pLeft -> nData) < 0){
                pNode = LLRotate(pNode);//LL型旋转
            } else pNode = LRRotate(pNode);//LR型旋转
        }
    } else if ( strcmp(nData,pNode -> nData) > 0)//插入到右子树中去
    {
        pNode -> pRight = Insert(nData, pNode -> pRight);
        if ( Height(pNode -> pRight) - Height(pNode -> pLeft) == 2)
        {
            if (strcmp(nData,pNode -> pRight -> nData) < 0){
                pNode = RLRotate(pNode);//RL型旋转
            } else pNode = RRRotate(pNode);//RR型旋转
        }
    }
    pNode -> nHeight = max(Height(pNode -> pLeft),Height(pNode -> pRight)) + 1;
    return pNode;
}

AVLTree* LLRotate(AVLTree* pNode)
{
    AVLTree* p1;
    p1 = pNode -> pLeft;
    pNode -> pLeft = p1 -> pRight;
    p1 -> pRight = pNode;
    pNode -> nHeight = max(Height(pNode -> pLeft),Height(pNode -> pRight)) + 1;
    p1 -> nHeight = max(Height(p1 -> pLeft),pNode -> nHeight) + 1;
    return p1;
}

AVLTree* RRRotate(AVLTree* pNode)
{
    AVLTree* p1;
    p1 = pNode -> pRight;
    pNode -> pRight = p1 -> pLeft;
    p1 -> pLeft = pNode;
    pNode -> nHeight = max(Height(pNode -> pLeft),Height(pNode -> pRight)) + 1;
    p1 -> nHeight = max(Height(p1 -> pRight),pNode -> nHeight) + 1;
    return p1;
}

AVLTree* LRRotate(AVLTree* pNode)
{
    pNode -> pLeft = RRRotate(pNode -> pLeft);
    return LLRotate(pNode);
}

AVLTree* RLRotate(AVLTree* pNode)
{
    pNode -> pRight = LLRotate(pNode -> pRight);
    return RRRotate(pNode);
}

void DeleteTree(AVLTree** ppRoot)
{
    if ( ppRoot == NULL || *ppRoot == NULL)
        return ;
    DeleteTree(&((*ppRoot) -> pLeft));
    DeleteTree(&((*ppRoot) -> pRight));
    free( *ppRoot);
    *ppRoot = NULL;
}

void PrintTree(AVLTree* pRoot,double sum)
{
    if (pRoot == NULL ) return;
    static int n = 0;
    PrintTree(pRoot -> pLeft,sum);
    printf("%s %.4lf\n",pRoot -> nData, pRoot -> Count*100/sum);
    PrintTree(pRoot -> pRight,sum);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值