我的排序功能有什么问题

时间:2016-05-03 17:34:34

标签: c

我很难理解为什么这种排序功能不起作用。它确实将节点放入排序顺序,但第一个节点总是在进程中丢失。这是我的代码(head变量是全局的):

void medianscore() {
   int i, j=0;
   int counter=0;
   struct student *curr=head;
   struct student *trail=head;
   struct student *temp=NULL;

   while (curr !=NULL)
   {
      curr=curr->next;    //couting the number of items I have in my list.
      counter++;          //this works fine.
   }

   curr=head->next;          // reseting the curr value for the 2nd position.

   for (i=0; i<counter; i++)
   {
      while (curr != NULL)
      {
          if (trail->grade > curr->grade)
          {
             temp=curr->next;      //bubble sort for the pointers.
             curr->next=trail;
             trail->next=temp;

             temp=curr;         //reseting trail and curr. curr gets back to be infront.
             curr=trail;
             trail=temp;

             if (j==0)   //i'm using j to determine the start of the loop so i won't loose the head pointer.
             {
                head=trail;
             }
          }
          j++;
          trail=curr;
          curr=curr->next;   //traversing thru the list. nested loop.
      }

      trail=head;
      curr=trail->next;
      curr->next=trail->next->next;  //traversing thru the list. outer loop.
      j=0;
   }
}

我做错了什么?

1 个答案:

答案 0 :(得分:0)

您的节点计数和使用变量ij来控制排序具有错误的代码味道。这些不应该是必要的。

我稍后会解决j和您的列表处理问题。对于i之外的外环,您可以为外循环的每次迭代维护一个标志,以便在该迭代结束时确定是否进行了交换。如果不是,那么就不需要执行另一次迭代。这种方法永远不会比现有技术执行更多的迭代,对于大多数输入,它将执行更少的。

但是,我在代码中看到的主要问题是它没有正确执行节点交换。假设你从这种情况开始......

prev --> trail --> curr --> Z

....你问的问题是{必须交换trailcurr,并假设你确定它们必须是。{1}}和trail。在这种情况下,您更新了next的{​​{1}}指针和curr,而不是prev,最后是链接看起来像这样:

prev ----V
       trail --> Z
curr ----^

此时,curr实际上已经丢失了 - 从列表头到Z的链接链不再通过它,你没有其他任何东西修复它。

我想你可能最终遇到了这个问题,部分原因是你的头部节点是一个特殊情况,因为没有任何东西链接到它。但这不是必须的。在不改变代码中其他地方如何使用链接列表的情况下,您可以创建一个指向头部的medianscore()本地虚拟节点:

struct student dummy;

dummy->next = head;

然后,您可以使用...

开始外循环的每次迭代
trail = &dummy;

...并在内循环测试中trail->next是否应与trail->next->next交换。当然,你的循环终止条件和交换需要稍微不同,但是你需要总是有一个指向交换对的第一个节点之前的节点的指针,因为这提供了,所以你可以更新它的{{1指针。

这样做有另一个好处:头节点不再需要在排序循环中进行任何特殊处理。相反,最后您只需设置next