简体   繁体   English

仅使用一个功能对链表进行合并排序,分段错误

[英]Mergesort on a linked-list using only one function, segmentation fault

I need to implement the function: struct listnode * mergesort(struct listnode *data) My professor provided the main() function testing code. 我需要实现以下功能: struct listnode * mergesort(struct listnode *data)我的教授提供了main()函数测试代码。 I only need to submit the mergesort function. 我只需要提交mergesort函数。 He told us to do it in C or C++ but the test code main() he gave us is in C. 他告诉我们用C或C ++来做,但是他给我们的测试代码main()是用C来做的。

This is my code right now: I can compile it but when I run it, it crashes. 这是我现在的代码:我可以编译它,但是当我运行它时,它会崩溃。 I checked debugger and it gave me segmentation fault. 我检查了调试器,这给了我分段错误。 I am also not really sure if this function is correct since I can't get past the testing point in the main(). 我也不太确定这个函数是否正确,因为我无法通过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);
}

if ( data == NULL )
    return;

You should return NULL. 您应该返回NULL。


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

If btail is set to head->next. 如果btail设置为head-> next。 If head->next is NULL, you're trying to check in the loop NULL->next != NULL which isn't a thing. 如果head-> next为NULL,则尝试在循环中检查NULL-> next!= NULL,这不是问题。


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

You need to check if btail is NULL before you check ->next. 在检查->下一个之前,您需要检查btail是否为NULL。 Just above you are setting btail = btail->next; 在上面,您正在设置btail = btail-> next; so it could be set to NULL. 因此可以将其设置为NULL。

Also the loop above has the same issue, you need to check null before you do stuff with next. 同样,上面的循环也有同样的问题,您需要在检查next之前先检查null。


There may be issues with the below code, but the above code needs way more error checking. 下面的代码可能有问题,但是上面的代码需要更多的错误检查方式。

Example function to merge two already sorted lists using pointer to pointer. 使用指针合并两个已排序列表的示例函数。 Since your'e only allowed a single function, you'll have to merge this logic into your mergesort() function. 由于您只允许使用一个函数,因此您必须将此逻辑合并到您的mergesort()函数中。 If this is homework, it may seem like you had too much help, but I'm not sure how else to explain the ideas shown in this example. 如果这是家庭作业,则似乎您获得了太多帮助,但是我不确定该如何解释该示例中显示的想法。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM