链接列表上的MergeSort

时间:2015-02-16 16:08:55

标签: c++ linked-list mergesort

我在编码方面相当糟糕所以我真的需要一些帮助,因为这个作业是在星期三之前完成的。我看到mergesort通常分为三个函数:(mergesort,sortedmerge,frontbacksplit等)。但我的教授基于数组的mergesort是在一个函数中完成的,所以我假设他希望我们只使用一个函数以及这个链表......(除非有可能在一个函数中实现一个函数)函数?)我们必须编写函数" struct listnode * mergesort(struct listnode * data)"并提交给他。到目前为止我所做的(我认为)是将链表拆分为2个子链表,但现在我不知道如何以递归方式"排序他们。教授告诉我们用C或C ++编写函数,但他在下面提供的测试代码是在C中。

#include <stdio.h>
#include <stdlib.h>

struct listnode { struct listnode * next;
                  long              value; } ;


//This is the function I need to write:
struct listnode * mergesort(struct listnode *data)
{   int temp, finished = 0;
    struct listnode *i, *j, *tail, *head, *ahead, *bhead, *atail, *btail;
    if ( a == NULL )
        return;
    head = data;
    tail = head->next;
    ahead = head;
    bhead = tail;
    i = ahead;
    j = bhead;
    tail = tail->next;
    while ( tail !=NULL ) {
        atail = tail;
        i->next = atail;
        i = i->next;
        tail = tail->next;
        btail = tail;
        j->next = btail;
        j = j->next;
        tail = tail->next;
    }

};

//Testing code provided by professor:
int main(void)
{
   long i;
   struct listnode *node, *tmpnode, *space;
   space =  (struct listnode *) malloc( 500000*sizeof(struct listnode));
   for( i=0; i< 500000; i++ )
   {  (space + i)->value = 2*((17*i)%500000);
      (space + i)->next = space + (i+1);
   }
   (space+499999)->next = NULL;
   node = space;
   printf("\n prepared list, now starting sort\n");
   node = mergesort(node);
   printf("\n checking sorted list\n");
   for( i=0; i < 500000; i++)
   {  if( node == NULL )
      {  printf("List ended early\n"); exit(0);
      }
      if( node->value != 2*i )
      {  printf("Node contains wrong value\n"); exit(0);
      }
      node = node->next;
   }
   printf("Sort successful\n");
   exit(0);
}

1 个答案:

答案 0 :(得分:0)

一般方法:

if( list contains 0 or 1 item)
    return the list;  // it is already sorted
split the list into halves;
mergesort( first part);
mergesort( second part);
merge sorted parts;
return the merged list;

列表包含0或1项条件:

head == NULL || head->next == NULL

要拆分列表,您需要找到它的中间位置:

ahead = atail = head;       // first item
btail = head->next;         // second item
while(btail->next != NULL)  // anything left
{
    atail = atail->next;
    btail = btail->next;
    if( btail->next)
        btail = btail->next;
}
bhead = atail->next;        // disconnect the parts
atail->next = NULL;

合并两个排序列表:

if(ahead->value <= bhead->value)  // set the head of resulting list
    head = tail = ahead, ahead = ahead->next;
else
    head = tail = bhead, bhead = bhead->next;

while(ahead && bhead)
    if(ahead->value <= bhead->value)  // append the next item
        tail = tail->next = ahead, ahead = ahead->next;
    else
        tail = tail->next = bhead, bhead = bhead->next;

if(ahead) // once one part got exhausted append the remaining other part
    tail->next = ahead;
else
    tail->next = bhead;