排序单链表 - 我不明白

时间:2012-06-09 19:55:34

标签: c linked-list

我正在查看http://publications.gbdirect.co.uk/c_book/chapter6/structures.html

中的示例6.7

(为方便起见粘贴在这里)

struct list_ele *
sortfun( struct list_ele *list )
{

      int exchange;
      struct list_ele *nextp, *thisp, dummy;

      /*
       * Algorithm is this:
       * Repeatedly scan list.
       * If two list items are out of order,
       * link them in the other way round.
       * Stop if a full pass is made and no
       * exchanges are required.
       * The whole business is confused by
       * working one element behind the
       * first one of interest.
       * This is because of the simple mechanics of
       * linking and unlinking elements.
       */

      dummy.pointer = list;
      do{
              exchange = 0;
              thisp = &dummy;
              while( (nextp = thisp->pointer)
                      && nextp->pointer){
                      if(nextp->data < nextp->pointer->data){
                              /* exchange */
                              exchange = 1;
                              thisp->pointer = nextp->pointer;
                              nextp->pointer =
                                      thisp->pointer->pointer;
                              thisp->pointer->pointer = nextp;
                      }
                      thisp = thisp->pointer;
              }
      }while(exchange);

      return(dummy.pointer);
}

我得到了基本的想法,但我无法解释那里发生的事情。有人可以更深入地解释但是以简单的方式解释在那个排序函数中会发生什么?

一般问题:

  • 为什么需要dummy.pointer = list;?然后在函数末尾返回dummy,为什么列表仍然排序?
  • 评论The whole business is confused by working one element behind the first one of interest.的含义是什么?

2 个答案:

答案 0 :(得分:2)

dummy是一个局部变量,首先设置为列表的开头。临时变量thisp设置为指向dummy,因此更新时,dummy指向的内容也会更新。因此,dummy.pointer最终将指向作为排序列表的新开头的元素。 list仍将指向列表的原始开头,因此返回值以便更新头指针。

我认为混淆意味着我们感兴趣的元素是nextp,而不是当前元素(或thisp)。也就是说,我们将列表中的下一个元素与当前元素进行比较,而不是将当前元素与前一个元素进行比较。我想那是令人困惑的,但我并没有真正找到它。

注意:这是Bubble Sort。更好的排序算法是Merge Sort,其实现位于http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html

答案 1 :(得分:2)

算法通过列表查看每个列表项和后面的列表项。如果它们出现故障,它们会被切换。然后重复该过程。最终将没有任何不合适的地方,没有任何东西可以切换;此时所有工作都已完成(由exchanged表示为零)。换句话说,最后一次通过列表,没有任何东西可以互换。

虚拟用于跟踪列表本身(如果前两个列表项被切换)。它被使用(而不是只是一个指向列表的简单指针,因为它也可以作为假的第一项,以便有一些东西可以比较列表中的原始第一项。它消除了对结果列表的特殊情况的需要第一项与原始列表的第一项不同。

在纸上进行处理,获得1,2,3和4项清单。然后你会看到它是如何工作的。当您完成它时,尝试放置列表以便开始并运行算法。然后在列表中交换2个项目并再次执行。

关于整个业务被混淆的评论,所有它指的是恕我直言,你必须跟踪单链表中的3个节点,以便交换其中两个节点。如果列表中有项目ACB(并且目标是列表为ABC),当您交换B和C时,您还必须有权访问A - 它的“下一个节点”指针必须从C更改为B. / p>