【发布时间】:2015-02-17 17:13:32
【问题描述】:
我需要实现的功能:struct listnode * mergesort(struct listnode *data)
我的教授提供了 main() 函数测试代码。我只需要提交合并排序功能。他告诉我们用 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);
}
【问题讨论】:
-
打开编译器警告并处理它们!!
if ( data == NULL) return;必须返回一个值。而mergesort(ahead); mergesort(bhead);则忽略返回的值。 -
啊,是的!有人告诉我,仅仅做
mergesort(ahead); mergesort(bhead);是行不通的,但我不确定如何让它返回新列表的头部。有人可以告诉我我应该怎么做吗? -
首先你应该有 |提前 = 合并排序(提前); | , | bhead = 合并排序(bhead); | .接下来,您需要清理合并代码。使用指向指针的指针可以简化创建合并列表: |节点 * pNew = NULL; | , |节点**ppNew = &pNew; | ,然后设置 *ppNew = 指向两个节点中较低节点的指针,并使用 | 推进 ppNew ppNew = &((*ppNew)->next); .下一个指向两个节点中较低节点的指针 = *ppNew;
-
@rcgldr 谢谢,我现在有了 ahead = mergesort(ahead) 和 bhead = mergesort(bhead)。还有,我很抱歉!我在编码方面非常业余,所以对于你所说的关于指针指针的事情,我不确定你是否可以澄清一下,因为我不太明白。现在,我无法弄清楚
if(data != NULL) ahead = atail = head = data; if(head->next !=NULL){ btail = head->next; } if(btail != NULL) while(btail->next != NULL)调试器在while(btail->next != NULL)处不断给我一个错误 -
@Jia - 有关合并列表的示例功能,请参见下面的答案。我没有经历多次重复的答案和问题,而是使用指向指针的指针发布了合并列表部分的示例代码。
标签: c sorting linked-list mergesort