使用链表合并排序 C 实现
Posted
技术标签:
【中文标题】使用链表合并排序 C 实现【英文标题】:Merge Sort C implementation with linked lists 【发布时间】:2022-01-03 02:45:52 【问题描述】:在尝试将排序与 C 中的链表合并时,我遇到了一个分段错误核心转储。似乎无法跟踪问题的根本原因:
这是我的节点结构:
typedef struct node0* node;
struct node0
int val;
node next;
node0;
这是我的分割函数:
node* divide(node head)
float mid = ceilf((float)length(head)/2);
node* ret = malloc(sizeof(node)*2);
node tmp1 = head;
while (mid>1)
tmp1 = tmp1->next;
mid--;
node tmp2 = tmp1->next;
tmp1->next = NULL;
ret[0] = head;
ret[1]=tmp2;
return ret;
这是我的合并函数:
node mergesorted(node head1, node head2)
node ret = NULL;
if(head1 == NULL) return head2;
else if(head2 == NULL) return head1;
if(head1->val <= head2->val)
ret = head1;
ret->next = mergesorted(head1->next, head2);
else
ret = head2;
ret->next = mergesorted(head1, head2->next);
return ret;
这是常规的归并排序算法:
node merged(node head)
if(length(head)>1)
node *lists = divide(head);
merged(lists[0]);
merged(lists[1]);
return mergesorted(lists[0], lists[1]);
主要:
int main()
node l1 = create_node(1);
l1->next = create_node(3);
l1->next->next = create_node(4);
l1->next->next->next= create_node(2);
l1 = merged(l1);
print_list(l1);
添加一些打印后,我得到以下日志:
deviding: 1-->3-->4-->2-->
devided into:
l1: 1-->3-->
l2: 4-->2-->
deviding: 1-->3-->
devided into:
l1: 1-->
l2: 3-->
merging: 1-->
with: 3-->
merged:1-->3-->
deviding: 4-->2-->
devided into:
l1: 4-->
l2: 2-->
merging: 4-->
with: 2-->
merged:2-->4-->
merging: 1-->3-->
with: 4-->
merged:1-->3-->4-->
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
在最终合并时,右侧列表指针似乎为空!
【问题讨论】:
【参考方案1】:由于以下片段而出现问题:
if(head1->val <= head2->val)
ret = head1;
ret->next = mergesorted(head1->next, head2);
else
ret = head2;
ret->next = mergesorted(head1, head2->next);
如果您看到,每次值变小或变大时,您都会分配一个新的“头”!这不应该是明确的意图。
只有当结果节点为empty
或NULL
时,您才需要创建/附加一个新头。
if(head1->val <= head2->val)
if(ret == NULL)
ret = head1;
ret->next = mergesorted(head1->next, head2);
else
if(ret == NULL)
ret = head2;
ret->next = mergesorted(head1, head2->next);
我在您的代码中没有发现任何其他问题。
【讨论】:
以上是关于使用链表合并排序 C 实现的主要内容,如果未能解决你的问题,请参考以下文章
剑指Offer-16.合并两个排序的链表(C++/Java)
LeetCode JavaScript实现 合并链表 题型汇总