从c中的链表数组返回排序列表
Posted
技术标签:
【中文标题】从c中的链表数组返回排序列表【英文标题】:Return a sorted list from an array of linked lists in 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
的两个参数。
【参考方案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;
【讨论】:
以上是关于从c中的链表数组返回排序列表的主要内容,如果未能解决你的问题,请参考以下文章