仅使用一个函数在链表上进行Mergesort功能

时间:2015-02-17 00:16:37

标签: c linked-list mergesort

我在编码时非常糟糕,我需要编写函数: struct listnode * mergesort(struct listnode * data)在C或C ++中,但测试代码在C中。

main()包含测试函数的测试代码。这是由教授给出的

我可以编译它,但是当我运行它时它会给我

prepared list, now starting sort

Process returned -1073741571 (0xC00000FD) execution time: 1.034 s

它不会超过这一点,所以我的功能肯定有问题,但我不确定它是什么。

#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)
{  
    if (data == NULL)
        return NULL;
    ///////Find the location of mid

    struct listnode *pRunToEnd = data;
    struct listnode *pRunToMid = data;
    struct listnode *pPreMid = NULL;
    while (pRunToEnd != NULL)
    {
        pRunToEnd = pRunToEnd->next;
        while (pRunToEnd!=NULL){
            pRunToEnd = pRunToEnd->next;
            if (pRunToEnd!=NULL){
                pRunToEnd = pRunToEnd->next;
        pPreMid = pRunToMid;
        pRunToMid = pRunToMid->next; }
        }
    }
    //////////Cut the list into 2 half
    if (pPreMid != NULL)
        pPreMid->next = NULL;
    /////Recursion
    mergesort(data);
    mergesort(pRunToMid);

    //////////Combine 2 half
    struct listnode *pFirst = data;
    struct listnode *pPreFirst = NULL;
    pPreMid = NULL;
    while (pFirst != NULL && pRunToMid!= NULL)
    {
        if(pFirst->value > pRunToMid->value)
        {
            pPreFirst = pFirst;
            pFirst = pFirst->next;
        }
        else
        {
            /////Chain the element of first list
            pPreFirst->next = pRunToMid;
            pPreMid = pRunToMid;
            pRunToMid = pRunToMid->next;
            pPreMid->next = NULL;
        }
    }

    ///////////////Chain the rest of second list
    if (pFirst == NULL)
    {
        pPreFirst->next = pRunToMid;
    }

    //////if pRunToMid is NULL, we do nothing because we have merged all elements in second list into first
    return(pPreFirst);


}


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 :(得分:1)

有些事情是错的。

  1. 缺少检查具有一个元素的列表的基本情况。为此,您可以更改

        if (data == NULL)
            return NULL;
    

        if (!data || !data->next)   // zero or one element list: already sorted
            return data;
    
  2. 找到中间位置的循环有问题;将其更改为

        while (pRunToEnd)
        {
            if (pRunToEnd = pRunToEnd->next)
                pRunToEnd = pRunToEnd->next;
            pPreMid = pRunToMid;
            pRunToMid = pRunToMid->next;
        }
    
  3. 正如rpattiso所写,你应该使用mergesort(data)mergesort(pRunToMid)的返回值作为排序列表的新头,所以改变

        mergesort(data);
        mergesort(pRunToMid);
    

        data = mergesort(data);
        pRunToMid = mergesort(pRunToMid);
    
  4. 关系运算符是向后 - 更改

            if(pFirst->value > pRunToMid->value)
    

            if (pFirst->value < pRunToMid->value)
    
  5. 在合并循环的else块中,您想要将第二个列表的元素插入第一个列表中,您忘记处理第二个列表的元素所在的情况插入在第一个的头部(即,成为列表的新头部),以及更新前面的元素指针pPreFirst,并且没有正确设置指针->next以进行链接到第一个清单。将块更改为

            {
                if (!pPreFirst) // no preceding element
                    data = pRunToMid;   // new list head
                else
                    pPreFirst->next = pRunToMid;    /////Chain the element of first list
                pPreFirst = pRunToMid;  // update pointer to preceding element
                pRunToMid = pRunToMid->next;
                pPreFirst->next = pFirst;   // chain to first list
            }
    
  6. 您正在返回已排序列表的尾部而不是其头部。变化

        return(pPreFirst);
    

        return data;