使用 for 循环时合并两个排序链表算法不起作用
所以在我的下面的代码中,我有两个列表。它们中的每一个都应该按升序排序,然后使用 SortedMerge()
将它们合并到一个列表中。 当我在主体中单独插入数字时,代码工作得很好:
int main()
{
struct Node *final = NULL;
struct Node *a = NULL;
struct Node *b = NULL;
insert(&a, 15);
insert(&a, 10);
insert(&a, 5);
insert(&b, 20);
insert(&b, 3);
insert(&b, 2);
final = SortedMerge(a, b);
printList(final);
return 0;
}
但就我而言,我不想单独插入数字,而是有两个数组并使用 for 循环将它们插入到列表中。该代码再次将它们合并在一起,但不按升序对它们进行排序:
int main()
{
int list1[] = { 15, 10, 5 };
int list2[] = { 20, 3, 2 };
struct Node *final = NULL;
struct Node *a = NULL;
struct Node *b = NULL;
int n1 = sizeof(list1) / sizeof(list1[0]);
int n2 = sizeof(list2) / sizeof(list2[0]);
for (int i = n1 - 1; i >= 0; i--) insert(&a, list1[i]);
for (int i = n2 - 1; i >= 0; i--) insert(&b, list2[i]);
final = SortedMerge(a, b);
printList(final);
return 0;
}
以下代码既单独插入,又使用 for
循环。 如果为了清楚起见,有人需要整体代码:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
struct Node
{
int data;
struct Node *next;
};
void MoveNode(struct Node **destRef, struct Node **source);
struct Node *SortedMerge(struct Node *a, struct Node *b)
{
struct Node *result = NULL;
struct Node **lastPointer = &result;
while (1) {
if (a == NULL) {
*lastPointer = b;
break;
}
else if (b == NULL) {
*lastPointer = a;
break;
}
if (a->data <= b->data)
MoveNode(lastPointer, &a);
else
MoveNode(lastPointer, &b);
lastPointer = &((*lastPointer)->next);
}
return (result);
}
void MoveNode(struct Node **destRef, struct Node **source)
{
struct Node *newNode = *source;
assert(newNode != NULL);
*source = newNode->next;
newNode->next = *destRef;
*destRef = newNode;
}
void insert(struct Node **head, int data)
{
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
if (newNode == NULL)
printf(" Memory can not be allocated.");
else {
newNode->data = data;
newNode->next = *head;
*head = newNode;
}
}
void printList(struct Node *node)
{
while (node)
{
printf("%d ", node->data);
node = node->next;
}
}
int main()
{
int list1[] = { 15, 10, 5 };
int list2[] = { 20, 3, 2 };
struct Node *final = NULL;
struct Node *a = NULL;
struct Node *b = NULL;
int n1 = sizeof(list1) / sizeof(list1[0]);
int n2 = sizeof(list2) / sizeof(list2[0]);
for (int i = n1 - 1; i >= 0; i--) insert(&a, list1[i]);
for (int i = n2 - 1; i >= 0; i--) insert(&b, list2[i]);
insert(&a, 15);
insert(&a, 10);
insert(&a, 5);
insert(&b, 20);
insert(&b, 3);
insert(&b, 2);
final = SortedMerge(a, b);
printList(final);
return 0;
}
So in my following code, I have two lists. Each of them should be sorted in increasing order and then merged together into one list with SortedMerge()
.
The code works just fine when in the main I insert the numbers separately:
int main()
{
struct Node *final = NULL;
struct Node *a = NULL;
struct Node *b = NULL;
insert(&a, 15);
insert(&a, 10);
insert(&a, 5);
insert(&b, 20);
insert(&b, 3);
insert(&b, 2);
final = SortedMerge(a, b);
printList(final);
return 0;
}
But in my case I don't want to insert numbers separately but rather have two arrays and insert them to the list using for loop. The code again merges them together, but does not sort them in increasing order:
int main()
{
int list1[] = { 15, 10, 5 };
int list2[] = { 20, 3, 2 };
struct Node *final = NULL;
struct Node *a = NULL;
struct Node *b = NULL;
int n1 = sizeof(list1) / sizeof(list1[0]);
int n2 = sizeof(list2) / sizeof(list2[0]);
for (int i = n1 - 1; i >= 0; i--) insert(&a, list1[i]);
for (int i = n2 - 1; i >= 0; i--) insert(&b, list2[i]);
final = SortedMerge(a, b);
printList(final);
return 0;
}
The following code has both insert separately and with for
loop.
If for clarity anybody will need the overall code:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
struct Node
{
int data;
struct Node *next;
};
void MoveNode(struct Node **destRef, struct Node **source);
struct Node *SortedMerge(struct Node *a, struct Node *b)
{
struct Node *result = NULL;
struct Node **lastPointer = &result;
while (1) {
if (a == NULL) {
*lastPointer = b;
break;
}
else if (b == NULL) {
*lastPointer = a;
break;
}
if (a->data <= b->data)
MoveNode(lastPointer, &a);
else
MoveNode(lastPointer, &b);
lastPointer = &((*lastPointer)->next);
}
return (result);
}
void MoveNode(struct Node **destRef, struct Node **source)
{
struct Node *newNode = *source;
assert(newNode != NULL);
*source = newNode->next;
newNode->next = *destRef;
*destRef = newNode;
}
void insert(struct Node **head, int data)
{
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
if (newNode == NULL)
printf(" Memory can not be allocated.");
else {
newNode->data = data;
newNode->next = *head;
*head = newNode;
}
}
void printList(struct Node *node)
{
while (node)
{
printf("%d ", node->data);
node = node->next;
}
}
int main()
{
int list1[] = { 15, 10, 5 };
int list2[] = { 20, 3, 2 };
struct Node *final = NULL;
struct Node *a = NULL;
struct Node *b = NULL;
int n1 = sizeof(list1) / sizeof(list1[0]);
int n2 = sizeof(list2) / sizeof(list2[0]);
for (int i = n1 - 1; i >= 0; i--) insert(&a, list1[i]);
for (int i = n2 - 1; i >= 0; i--) insert(&b, list2[i]);
insert(&a, 15);
insert(&a, 10);
insert(&a, 5);
insert(&b, 20);
insert(&b, 3);
insert(&b, 2);
final = SortedMerge(a, b);
printList(final);
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的
SortedMerge
函数需要两个按升序排序的列表,并将它们按升序合并为一个列表。对于第一个示例:(
注意:
insert
在列表的前面插入。)a
: 5, 10, 15。Listb
: 2, 3, 20列表
a
和b
按升序排列,因此对SortedMerge
有效。对于第二个示例:(
注意:
insert
在列表的前面插入。)a
: 15, 10, 5b
: 20, 3, 2列表
a
和b
按降序排列,因此对于SortedMerge
无效。对于第三个(组合示例):
a
:5, 10, 15, 15, 10, 5b
:2, 3, 20, 20, 3, 2列表
a
和b
未排序,因此对于SortedMerge
无效。Your
SortedMerge
function expects two lists sorted in ascending order and merges them into a single list in ascending order.For the first example:
(Note:
insert
inserts at the front of the list.)a
: 5, 10, 15.b
: 2, 3, 20Lists
a
andb
are in ascending order so are valid forSortedMerge
.For the second example:
(Note:
insert
inserts at the front of the list.)a
: 15, 10, 5b
: 20, 3, 2Lists
a
andb
are in descending order so are not valid forSortedMerge
.For the third (combined example):
a
: 5, 10, 15, 15, 10, 5b
: 2, 3, 20, 20, 3, 2Lists
a
andb
are not sorted so are not valid forSortedMerge
.问题是
SortedMerge
假设列表按升序排序,而您打破了这个假设:您将元素从数组中的最后一个元素添加到第一个元素(该函数称为insert
,一个令人困惑的选择),但数组的内容已经按降序排列,因此您可以有效地按降序排列列表。然后您在前面添加更多元素,因此这些列表是未排序的。insert
函数以将新节点插入到正确的位置。这是使用后者的修改版本:
The problem is
SortedMerge
assumes the lists are sorted in ascending order and you break this assumption: you prepend the elements from the last to the first in the arrays (the function is calledinsert
, a confusing choice), but the contents of the arrays in already in decreasing order so you effectively get the list sorted in decreasing order. Then you prepend more elements, so these lists are unsorted.for (int i = 0; i < n1; i++) insert(&a, list1[i]);
and do not insert more elements orinsert
function to insert the new node in the proper place.Here is a modified version using the latter: