【问题标题】:Merge Sort C implementation with linked lists使用链表合并排序 C 实现
【发布时间】: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)

在最终合并时,右侧列表指针似乎为空!

【问题讨论】:

    标签: c pointers linked-list mergesort


    【解决方案1】:

    由于以下片段而出现问题:

        if(head1->val <= head2->val){
            ret = head1;
            ret->next = mergesorted(head1->next, head2);
        } else {
            ret = head2;
            ret->next = mergesorted(head1, head2->next);
        }
    

    如果您看到,每次值变小或变大时,您都会分配一个新的“头”!这不应该是明确的意图。

    只有当结果节点为emptyNULL 时,您才需要创建/附加一个新头。

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

    我在您的代码中没有发现任何其他问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-29
      • 2014-10-31
      • 1970-01-01
      • 2020-10-07
      • 1970-01-01
      • 2018-05-27
      • 2013-08-11
      • 1970-01-01
      相关资源
      最近更新 更多