添加到已排序的链接列表

时间:2012-03-22 22:38:59

标签: c linked-list

我正在尝试让我的程序将分数插入有序链表中的某个位置。当我启动它时它编译很好但崩溃了。链接列表并不是我的专长,所以我确定我在某个地方犯了错误。 p [i] .score和p [i] .name在这段代码之前定义,列表最初为空。

struct highScore
{
    char name[10];
    int score;
    struct highScore *next;
};
struct highScore *head,*currentScore,*newScore, *temp;

if(head==NULL)
{
    head = currentScore = newScore;
    currentScore->score = p[i].score;
    strcpy(currentScore->name, p[i].name);
}
else
{
    currentScore = head;      

    while (currentScore->next != NULL)
    {
        while(p[i].score < currentScore->score)
        {
            currentScore = currentScore->next;
            if (currentScore->next->score < p[i].score)
            {
                newScore = (struct highScore *)malloc(sizeof(struct highScore));

                newScore->score = p[i].score;
                strcpy(newScore->name, p[i].name);

                temp = currentScore->next;
                currentScore->next = newScore;
                currentScore = newScore;
                currentScore->next = temp;
            }
        }
    }
}

3 个答案:

答案 0 :(得分:1)

您当前的代码有点混乱(正如其他人所说)。

你需要的是伪代码,是这样的:

new_entry = create_new_entry(data); /* allocate the new stuff */
for (some loop to find where new_entry is to insert)
    ... loop contents ...
insert new_entry;

单链表的棘手部分是你只能进行“先插入”操作,如下所示:

new_entry->next = what_new_goes_before;
what_new_goes_after->next = new_entry;

这要求有“new_entry追求的东西”。这是特殊情况测试的地方:

if (head == NULL)

来自:如果headNULL,则您无法获得现有条目。不幸的是,新条目首先出现的情况,所以你需要测试这两个:

if (head == NULL || goes_before(new_entry, head)) {
    /* i.e., there is no head yet, or new_entry goes before head */
    new_entry->next = head;
    head = new_entry;
} else {
    /* there is something for new_entry to go after, so find it */
    for (old_entry = head; !goes_before(new_entry, old_entry);)
        prev = old_entry;
        if ((old_entry = old_entry->next) == NULL)
            break;
    new_entry->next = old_entry;
    prev->next = new_entry;
}

然而,这里有一个非常有用的技巧,在C中指针指针。而不是写一个必须至少运行一次的循环(设置prev以上 - 注意我们知道第一次旅行中!goes_before()的结果),我们可以有一个指针变量{{1}这将指向一些pp指针:

struct highScore *

最初,我们会向struct highScore **pp, *p; 提出这一点。当我们通过循环尝试找到新条目之前的项时,我们将其更改为指向每个旧条目的head指针struct highScore *

next

当new_entry在for (pp = &head; !goes_before(new_entry, p = *pp); pp = &p->next) continue; 之前(其值现在位于*pp)时,循环终止,所以现在我们只需要设置新条目的p并更新next

*pp

并且整个过程分为四行(加上第五个声明行)。

答案 1 :(得分:0)

  1. 将代码分解为函数。例如,“initialize()”,“insert()”,“find()”和“delete()”可能都是有用的函数。

  2. 不要使用全局变量。例如,“* head”和“* currentScore”可能是您考虑制作全局变量的唯一变量。

  3. 为每个功能编写测试程序。

  4. 单步调试调试器下的每个测试程序。

  5. 恕我直言.. PSM

    PS: 例如:

    struct *highScore
    insert (struct ** head, struct *highScore newScore)
    {
      struct *hiScore currentScore;
    
      // Assumes "newScore" element is already filled in
      if(*head==NULL)
      {
        *head = newScore;
        newScore->next = NULL;
        return newScore;
      }
      else
      {
        currentScore = *head;      
        while (currentScore->next != NULL)
        {
           ...
    

答案 2 :(得分:0)

  1. 该行

    head = currentScore = newScore;

    您尚未初始化newScore - 因此if声明的其余部分注定失败。

  2. 您是按顺序添加商品,还是列表应按顺序排列?