【问题标题】:Return a sorted list from an array of linked lists in c从c中的链表数组返回排序列表
【发布时间】:2021-08-12 19:26:06
【问题描述】:

我最后在这里要完成的是对一个包含多个链表的结构数组进行排序,并返回 1 个合并列表并进行排序。

例子

Input: [1->4->5, 1->3->4, 2->6] 
Output: 1->1->2->3->4->4->5->6 

输入是数组,如示例中所示,其中有 3 个不同的列表排序错误。

输出是最终的排序列表。

我试图做的是尝试像普通结构数组一样访问数组,然后一次排序 2 个。

我的代码

#include <stddef.h>


#ifndef STRUCT_LISTNODE
#define STRUCT_LISTNODE
typedef struct s_listnode
{
    int val;
    struct s_listnode* next;
} listnode;
#endif

#ifndef STRUCT_LISTNODE_ARRAY
#define STRUCT_LISTNODE_ARRAY
typedef struct s_listnode_array
{
    int size;
    listnode **array;
} listnode_array;
#endif


listnode* sort(listnode* first, listnode* second){
    listnode* newNode;
    if(first == NULL && second == NULL)
        return NULL;
    if (first == NULL)
        return second;
    if (second == NULL)
        return first;

// checking if the value on the first list bigger than the second or equal
    if (first->val >= second->val) {\
   // if yes that means that the second should be first.
        newNode = second;
        newNode->next = sort(first, second->next);
    } else {
        newNode = first;
        newNode->next = sort(first->next, second);
    }
    return newNode;
}

listnode* merge_k_sorted_lists(listnode_array* head)
{
    listnode *newNode;
   for(int i = 0 ; i < head->size; i++){
       newNode = sort(head->array[0], head->array[i]);
   }

   return newNode;
}

当我尝试运行我的代码时,我根本没有得到任何返回值。

【问题讨论】:

  • 是时候学习如何使用 调试器 在监控变量及其值的同时逐语句执行代码。然后进入sort的递归调用。我还建议您在创建列表时同时使用笔和纸来“绘制”列表。在merge_k_sorted_lists 函数中,所有这些都应该让您更容易看到newNode 的变化以及它的变化。
  • 你的函数sort真的在做merge
  • merge_k_sorted_lists 中循环的第一次迭代将列表 0 用于sort 的两个参数。

标签: arrays c sorting struct linked-list


【解决方案1】:

我做了一些更改,现在它似乎工作得更好,但有一个问题。

如果输入是一个具有 [[],[1]] 的数组并且预期的输出应该是 [1] 我没有得到返回并且我得到 SIGSEGV(信号 11)

#include <stddef.h>


#ifndef STRUCT_LISTNODE
#define STRUCT_LISTNODE
typedef struct s_listnode
{
    int val;
    struct s_listnode* next;
} listnode;
#endif

#ifndef STRUCT_LISTNODE_ARRAY
#define STRUCT_LISTNODE_ARRAY
typedef struct s_listnode_array
{
    int size;
    listnode **array;
} listnode_array;
#endif


listnode* sort(listnode* first, listnode* second){
     
    if(first == NULL && second == NULL)
        return NULL;
    if (first == NULL){
        return second;
    }
    if (second == NULL)
        return first;

    
    listnode* newNode;
    
    if (first->val > second->val) {
        newNode = second;
        newNode->next = sort(first, second->next);
    } else {
        newNode = first;
        newNode->next = sort(first->next, second);
    }
    return newNode;
}


listnode* merge_k_sorted_lists(listnode_array* nodeArr)
{
    listnode *newNode;
    
    if(nodeArr->array[0]->next == NULL) 
        return nodeArr->array[0];
    if(nodeArr->size < 2)
        return nodeArr->array[0];

    for(int i = 1 ; i < nodeArr->size; i++)
        newNode = sort(nodeArr->array[0], nodeArr->array[i]);

   return newNode;
}

【讨论】:

    【解决方案2】:

    修复并简化了 merge_k_sorted_lists()。从 sort() 中删除了不需要的 if 语句。这与链表的自下而上合并排序中的第二个循环基本相同。递归的sort(),实际上是合并,对于大列表会导致栈溢出。

    https://en.wikipedia.org/wiki/Merge_sort#Bottom-up_implementation_using_lists

    #include <stdio.h>
    
    #ifndef STRUCT_LISTNODE
    #define STRUCT_LISTNODE
    typedef struct s_listnode
    {
        int val;
        struct s_listnode* next;
    } listnode;
    #endif
    
    #ifndef STRUCT_LISTNODE_ARRAY
    #define STRUCT_LISTNODE_ARRAY
    typedef struct s_listnode_array
    {
        int size;
        listnode **array;
    } listnode_array;
    #endif
    
    listnode* sort(listnode* first, listnode* second){
    listnode* newNode;
        if (first == NULL)
            return second;
        if (second == NULL)
            return first;
        if (first->val > second->val) {
            newNode = second;
            newNode->next = sort(first, second->next);
        } else {
            newNode = first;
            newNode->next = sort(first->next, second);
        }
        return newNode;
    }
    
    listnode* merge_k_sorted_lists(listnode_array* nodeArr)
    {
    listnode *newNode = NULL;
        for(int i = 0 ; i < nodeArr->size; i++)
            newNode = sort(newNode, nodeArr->array[i]);
        return newNode;
    }
    
    int main()
    {
    listnode list0[3] = {{1, list0+1}, {4,list0+2}, {5,NULL}};
    listnode list1[3] = {{1, list1+1}, {3,list1+2}, {4,NULL}};
    listnode list2[2] = {{2, list2+1}, {6,NULL}};
    listnode *lists[3] = {list0, list1, list2};
    listnode_array array[3] = {3, lists};
    listnode *result, *tmp;
        result = merge_k_sorted_lists(array);
        for(tmp = result; tmp; tmp = tmp->next)
            printf("%1d ", tmp->val);
        printf("\n");
        return 0;
    }
    

    使用虚拟节点的非递归合并

    listnode* sort(listnode* first, listnode* second){
    listnode dMrg = {0, NULL};              /* dummy node */
    listnode *pMrg = &dMrg;                 /* ptr to node in merged list */
        if (first == NULL)                  /* check for empty lists */
            return second;
        if (second == NULL)
            return first;
        while(1){                           /* merge the lists */
            if(first->val > second->val){
                pMrg = pMrg->next = second;
                second = second->next;
                if(second == NULL){
                    pMrg->next = first;
                    break;
                }
            }else{
                pMrg = pMrg->next = first;
                first = first->next;
                if(first == NULL){
                    pMrg->next = second;
                    break;
                }
            }
        }
        return dMrg.next;                   /* return merged list */
    }
    

    使用指针的非递归合并

    listnode* sort(listnode* first, listnode* second){
    listnode *pMrg;                         /* merged list */
    listnode **ppMrg = &pMrg;               /* ptr to ptr to node in merged list */
        if (first == NULL)                  /* check for empty lists */
            return second;
        if (second == NULL)
            return first;
        while(1){                           /* merge the lists */
            if(first->val > second->val){
                *ppMrg = second;
                ppMrg = &(second->next);
                second = *ppMrg;
                if(second == NULL){
                    *ppMrg = first;
                    break;
                }
            }else{
                *ppMrg = first;
                ppMrg = &(first->next);
                first = *ppMrg;
                if(first == NULL){
                    *ppMrg = second;
                    break;
                }
            }
        }
        return pMrg;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多