链接列表上的Mergesort只使用一个函数,分段错误

时间:2015-02-17 17:13:33

标签: c sorting linked-list mergesort

我需要实现这个功能:struct listnode * mergesort(struct listnode *data) 我的教授提供了main()函数测试代码。我只需要提交mergesort函数。他告诉我们用C或C ++做,但是他给我们的测试代码main()是在C。

这是我现在的代码: 我可以编译它,但是当我运行它时,它会崩溃。我检查了调试器,它给了我分段错误。我也不确定这个函数是否正确,因为我无法通过main()中的测试点。


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

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


struct listnode * mergesort(struct listnode *data)
{   int temp, finished = 0;
    struct listnode *tail, *head, *ahead, *bhead, *atail, *btail;
    if ( data == NULL )
        return;
    //Split
    ahead = atail = head = data;       // first item
    btail = head->next;         // second item
    while(btail->next != NULL)  // anything left
    {
    atail = atail->next;
    btail = btail->next;
    if( btail->next != NULL)
        btail = btail->next;
    }
    bhead = atail->next;        // disconnect the parts
    atail->next = NULL;

    //sort
    mergesort(ahead);
    mergesort(bhead);

    //merge
    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 != NULL)
        tail->next = ahead;
    else
        tail->next = bhead;
    return(head);
}


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);
}

2 个答案:

答案 0 :(得分:1)

if ( data == NULL )
    return;

你应该返回NULL。


btail = head->next;         // second item
while(btail->next != NULL)  // anything left
{

如果btail设置为head-&gt; next。如果head-&gt; next为NULL,你试图检查循环NULL-&gt; next!= NULL,这不是一件事。


if( btail->next != NULL)
    btail = btail->next;
}

在检查之前,你需要检查btail是否为NULL - >接下来。在上面你设置btail = btail-&gt; next;所以它可以设置为NULL。

上面的循环也存在同样的问题,你需要先检查null,然后再做下一步。


以下代码可能存在问题,但上述代码需要进行更多错误检查。

答案 1 :(得分:0)

使用指向指针合并两个已经排序的列表的示例函数。由于您只允许使用单个函数,因此您必须将此逻辑合并到mergesort()函数中。如果这是作业,可能看起来你有太多的帮助,但我不确定如何解释这个例子中显示的想法。

NODE * MergeLists(NODE *pSrc1, NODE *pSrc2)
{
NODE *pDst = NULL;                      /* destination head ptr */
NODE **ppDst = &pDst;                   /* ptr to head or prev->next */
    while(1){
        if(pSrc1 == NULL){
            *ppDst = pSrc2;
            break;
        }
        if(pSrc2 == NULL){
            *ppDst = pSrc1;
            break;
        }
        if(pSrc2->data < pSrc1->data){  /* if src2 < src1 */
            *ppDst = pSrc2;
            pSrc2 = *(ppDst = &(pSrc2->next));
            continue;
        } else {                        /* src1 <= src2 */
            *ppDst = pSrc1;
            pSrc1 = *(ppDst = &(pSrc1->next));
            continue;
        }
    }
    return pDst;
}