heap找中位数的算法在oj上显示runtime error,求解答

题目描述
编写用两个 Heap 实现动态查找中位数的程序

你最终编写的程序的整体复杂度应该低于 Θ(n^2),否则可能会因为超时无法通过评测系统中的全部测试

现有 n 个学生的成绩和姓名,每当输入一个学生的信息,你需要计算学生成绩的中位数,并输出位于中间的学生的成绩和姓名

输入格式
第一行为 n,表示接下来有 n 行,每行描述了一个学生的成绩和姓名,其格式如下:

<成绩> <姓名> 表示一个学生的成绩和他的姓名,<成绩>和<姓名>之间有一个空格

<姓名> 由 1 到 16 个大小写字母组成,<成绩> 为 0 到 1000000 的整数

测试数据中不会含有<成绩>相同的数据,从而中位数是唯一的

测试数据中可能含有<姓名>相同的数据,可视为碰巧重名的不同学生,你在编程的时候不需要特殊考虑姓名是否相同的问题

输出格式
需要输出 n 行,每读入一条数据就可以输出一行

在第 m 行中输出时只需要考察(按输入顺序)前 m 个学生,输出它们之中成绩位于中间的学生的成绩和姓名。

当 m 为奇数时,中位数唯一,是成绩在第 (m+1)/2 的学生,输出格式为:

<成绩> <姓名>

当 m 为偶数时,中位数有两个,分别是成绩在第 m/2 的学生和成绩在第 m/2+1 的学生,输出格式为(先输出成绩低的,后输出成绩高的,即<成绩1><<成绩2>):

<成绩1> <姓名1> <成绩2> <姓名2>

同一行的<成绩>和<姓名>之间有一个空格

例如:在第 5 行输出的是前 5 个学生中成绩排第 3 的学生的成绩和姓名;在第 6 行输出的是前 6 个学生中成绩排第 3 的和成绩排第 4 的学生的成绩和姓名

输入范例
8
148 GHuMEAyLnLFDxFI
1 Alexstrasza
573 ScXGgbWkFNQdU
529 NFoZVsrTKj
100 Alexstrasza
884 pGgXrpNrvY
61 wCYSYyCQP
1000 Alexstrasza
输出范例
148 GHuMEAyLnLFDxFI
1 Alexstrasza 148 GHuMEAyLnLFDxFI
148 GHuMEAyLnLFDxFI
148 GHuMEAyLnLFDxFI 529 NFoZVsrTKj
148 GHuMEAyLnLFDxFI
148 GHuMEAyLnLFDxFI 529 NFoZVsrTKj
148 GHuMEAyLnLFDxFI
148 GHuMEAyLnLFDxFI 529 NFoZVsrTKj
数据规模
n <= 10000

我写的代码:

#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#define LEN 16

struct Node
{
    int score;
    char name[LEN];
};

void up(struct Node*T, int n,int i)
{
    int k = i;
    int val = T[i].score;
    int L, j=-1;
    char temp[LEN];
    strcpy(temp,T[i].name);

    while(j!=k)
    {
        j = k;
        if(j>0&&T[(j-1)/2].score<val)
        {
            k=(j-1)/2;
            T[j].score=T[k].score;
            strcpy(T[j].name,T[k].name);
        }

    }
    if (k != i)
    {
        T[k].score = val;
        strcpy(T[k].name,temp);
    }
}
void reup(struct Node*T, int n,int i)
{
    int k = i;
    int val = T[i].score;
    int L, j=-1;
    char temp[LEN];
    strcpy(temp,T[i].name);

    while(j!=k)
    {
        j = k;
        if(j>0&&T[(j-1)/2].score>val)
        {
            k=(j-1)/2;
            T[j].score=T[k].score;
            strcpy(T[j].name,T[k].name);
        }

    }
    if (k != i)
    {
        T[k].score = val;
        strcpy(T[k].name,temp);
    }
}
void sift(struct Node*T, int n, int i)
{
    int k = i;
    int val = T[i].score;
    int L, j=-1;
    char temp[LEN];
    strcpy(temp,T[i].name);

    while(j!=k)
    {
        j = k;
        if (2 * j + 1 < n)
        {
            L = 1;

            if (2 * j + 2 <n && T[2 * j + 2].score > T[2 * j + 1].score)
            {
                L = 2;
            }
            if (T[2 * j + L].score > val)
            {
                T[k].score = T[2 * j + L].score;
                strcpy(T[k].name,T[2 * j + L].name);
                k = 2 * j + L;
            }
        }
    }
    if (k != i)
    {
        T[k].score = val;
        strcpy(T[k].name,temp);
    }
}
void resift(struct Node*T, int n, int i)
{
    int k = i;
    int val = T[i].score;
    int L, j=-1;
    char temp[LEN];
    strcpy(temp,T[i].name);

    while(j!=k)
    {
        j = k;
        if (2 * j + 1 < n)
        {
            L = 1;

            if (2 * j + 2 <n && T[2 * j + 2].score <T[2 * j + 1].score)
            {
                L = 2;
            }
            if (T[2 * j + L].score<val)
            {
                T[k].score = T[2 * j + L].score;
                strcpy(T[k].name,T[2 * j + L].name);
                k = 2 * j + L;
            }
        }
    }
    if (k != i)
    {
        T[k].score = val;
        strcpy(T[k].name,temp);
    }
}

int main()
{
    int n;
    scanf("%d",&n);
    struct Node*minT;
    struct Node*maxT;
    minT=(struct Node*)malloc(sizeof(struct Node)*10000);
    maxT=(struct Node*)malloc(sizeof(struct Node)*10000);
    int  score;
    char name[LEN];

    for(int i=0;i<n;i++)
    {
        scanf("%d %s",&score,&name);
        if(i==0)
        {
            maxT[0].score=score;
            strcpy(maxT[0].name,name);
            printf("%d %s\n",maxT[0].score,maxT[0].name);
        }
        else if(i==1)
        {
            if(score>maxT[0].score)
            {
                minT[0].score=maxT[0].score;
                strcpy(minT[0].name,maxT[0].name);
                maxT[0].score=score;
                strcpy(maxT[0].name,name);
            }
            else
            {
                minT[0].score=score;
                strcpy(minT[0].name,name);
            }
            printf("%d %s %d %s\n",minT[0].score,minT[0].name,maxT[0].score,maxT[0].name);
        }
        else
        {
             if(i%2==0)
            {
                if(score>minT[0].score)
                {
                    maxT[i/2].score=score;
                    strcpy(maxT[i/2].name,name);
                    reup(maxT,i/2+1,i/2);
                }
                else
                {
                        maxT[i/2].score=minT[0].score;
                        strcpy(maxT[i/2].name,minT[0].name);
                        reup(maxT,i/2+1,i/2);
                        minT[0].score=score;
                        strcpy(minT[0].name,name);
                        sift(minT,i/2,0);
                }

               printf("%d %s\n",maxT[0].score,maxT[0].name);
            }
            else
            {
                if(score>maxT[0].score)
                {
                    minT[i/2].score=maxT[0].score;
                    strcpy(minT[i/2].name,maxT[0].name);
                    up(minT,i/2+1,i/2);
                    maxT[0].score=score;
                    strcpy(maxT[0].name,name);
                    resift(maxT,i/2+1,0);
                }
                else
                {
                    minT[i/2].score=score;
                    strcpy(minT[i/2].name,name);
                    up(minT,i/2+1,i/2);
                }
                 printf("%d %s %d %s\n",minT[0].score,minT[0].name,maxT[0].score,maxT[0].name);
            }
        }
    }
    return 0;
}


说实话,不知道你写的什么,但是有一点就是非常啰嗦。要是明天有空的话就写一个给你参考参考。



```c

#define LEN 17 //最后一个结束符要加上1个字节

typedef struct ScoreNode
{
    int score;
    char name[LEN];
    struct ScoreNode *prev;
    struct ScoreNode *next;
} ScoreNode;

int main()
{
    int f, i, n, l;
    ScoreNode *psnadd, *psntravel, *psnMid, *psnLast;
    ScoreNode **ppsnMid;

    scanf("%d", &n);

    if(n<1 || n>10000)
    {
        return 1; //题目中如果有错误代码,那就按题目要求来。
    }

    f = 1;
    i = 0;
    l = 0;
    psnLast = (ScoreNode *)malloc(sizeof(ScoreNode)); //此节点放在链表末尾不储存学生信息
    psnLast->score = 1000001;
    psnLast->prev = psnLast;
    psnLast->next = psnLast;
    psnMid = psnLast;
    ppsnMidList = (ScoreNode **)malloc(sizeof(ScoreNode *)*(n + (n>>1)));

    while(i < n)
    {
        psnadd = (ScoreNode *)malloc(sizeof(ScoreNode));
        scanf("%d %s", &psnadd->score, psnadd->name); //成绩和名字自己考虑是否需要验证准确性

        if(psnadd->score < psnMid->score)
        {
            f--;
            psntravel = psnLast->next;
        }
        else
        {
            f++;
            psntravel = psnMid;
        }

        while(psnadd->score > psntravel->score)
        {
            psntravel = psntravel->next;
        }

        psnadd->prev = psntravel->prev;
        psnadd->prev->next = psnadd;
        psnadd->next = psntravel;
        psntravel->prev = psnadd;

        if(f == 0)
        {
            psnMid = psnMid->prev;
        }
        else if(f == 1)
        {
            psnMid = psnMid->next;
        }

        i++;
        f = i & 1;
        ppsnMidList[l++] = psnMid;

        if(f == 0)
        {
            ppsnMidList[l++] = psnMid->next;
        }
    }

    i = l - f;
    l = 0;

    while(l < i)
    {
        printf("%d %s/n%d %s %d %s/n", ppsnMidList[l]->score, ppsnMidList[l]->name, ppsnMidList[l+1]->score, ppsnMidList[l+1]->name, ppsnMidList[l+2]->score, ppsnMidList[l+2]->name);
        l = l + 3;
    }

    if(f == 1)
    {
        printf("%d %s/n", ppsnMidList[l]->score, ppsnMidList[l]->name);
    }

    psntravel = psnLast->prev;

    for(; ; )
    {
        free(psntravel->next);

        if(psntravel->prev == psnLast)
        {
            break;
        }

        psntravel = psntravel->prev;
    }

    free(psntravel);
    free(ppsnMidList);

    return 0;
}

```