【发布时间】:2019-12-29 01:05:44
【问题描述】:
我应该编写一个函数来合并(将一个放在另一个的末尾)两个单链表。用户在控制台中输入一系列数字,例如:1 2 3 4 0(0 表示输入结束,不是列表的元素)。这些数字被放入链表,链表现在看起来像这样:1 2 3 4。这个过程再次重复,直到我们有两个不同的链表。然后合并函数称为“void merge(struct Node head1, struct Node head2)”。打印新列表后程序结束。
我的想法是首先让我的指针指向第一个列表的末尾,然后创建一个 while 循环,该循环将遍历另一个列表,并使第一个列表的下一个元素成为第二个列表的当前元素列表。
typedef struct Element Element;
struct Element
{
int data;
Element *next;
};
Element *addNew(int data)
{
Element *newN = (Element*)malloc(sizeof(Element));
newN->data = data;
newN->next = NULL;
return newN;
}
Element *add_on_beginning(Element *head, Element *newN)
{
newN->next = head;
return newN;
}
Element *add_on_end(Element *head, Element *newN)
{
if(head == NULL)
{
return newN;
}
Element *temp = head;
while(temp->next != NULL)
{
temp = temp->next;
}
temp->next = newN;
return head;
}
void printElement(Element *element)
{
printf("%d ", element->data);
}
void printList(Element *head)
{
Element *temp = head;
while(temp != NULL)
{
printElement(temp);
temp = temp->next;
}
}
void merge(Element *head1, Element *head2)
{
Element *temp1 = head1;
Element *temp2 = head2;
while(temp1->next != NULL)
{
temp1 = temp1->next;
}
while(temp2->next != NULL)
{
temp1->next = temp2;
temp2 = temp2->next;
}
}
int main()
{
Element *head1 = NULL;
Element *head2 = NULL;
int arr[1000];
char temp1;
char temp2;
int i = 0;
int j = 0;
printf("Input the first set of elements: \n");
while(temp1 != '\n')
{
scanf("%d%c", &arr[i], &temp1);
if(arr[i] == 0)
{
break;
}
head1 = add_on_end(head1, addNew(arr[i]));
i++;
}
printf("Input the second set of elements: \n");
while(temp2 != '\n')
{
scanf("%d%c", &arr[j], &temp2);
if(arr[j] == 0)
{
break;
}
head2 = add_on_end(head2, addNew(arr[j]));
j++;
}
merge(head1, head2);
printList(head1);
return 0;
}
所以由于某种原因,该函数只读取第二个列表的最后两个元素。
输入:
1 2 3 4 0
5 6 7 8 0
输出:
1 2 3 4 7 8
我应该得到的结果是
输入:
1 2 3 4 0
5 6 7 8 0
输出:
1 2 3 4 5 6 7 8
【问题讨论】:
-
不是你的问题,但我建议坚持使用更简单的
scanf调用。不要打扰%c并查看是否有换行符。但是请检查scanf的返回值,然后继续它是 1。 -
您想让第一个列表末尾的
next元素指向第二个列表的head。在merge(),根本不需要扫描第二个列表。 -
这确实有效,我不敢相信我这么愚蠢没有看到...所以对于将来查看这篇文章的任何人,在函数合并中,只需摆脱第二个while循环,而不是写temp->next = head2,仅此而已。 @SteveSummit 感谢所有帮助!
-
如所写,您的
merge函数无法处理第一个列表为 NULL 的情况。为了处理这个问题(并与编写其他函数的方式保持一致,例如add_on_end),您希望merge返回新列表。 -
虽然标签 merge 的描述足够通用,但我会避免使用术语 merge 来表示没有 O(1) "random 的数据结构联合"/indexed access 如果它没有保持每个结构单独显示的顺序。 join, chain, concatenate, (unite?), ...
标签: c algorithm merge linked-list singly-linked-list