如何在C++中合并已排序的列表
How to merge sorted lists in C++?
我知道这个问题已经被问了很多次,部分答案是关于合并排序的问题,但我似乎不太明白。
这是我的代码:
#include <iostream>
using namespace std;
struct listNode {
int info;
struct listNode *next;
};
struct listNode * addHead(struct listNode* head, int k);
void printAll(struct listNode *head);
struct listNode * deleteLast(struct listNode *head);
struct listNode * append(struct listNode *a, struct listNode *b);
struct listNode * zip(struct listNode *a, struct listNode *b);
struct listNode * merge(struct listNode *a, struct listNode*b);
int main()
{
listNode *list1 = 0;
listNode *list2 = 0;
listNode *list3 = 0;
listNode *list4 = 0;
listNode *list5 = 0;
//fill list1
list1 = addHead(list1, 6);
list1 = addHead(list1, 4);
list1 = addHead(list1, 2);
//fill list2
list2 = addHead(list2, 3);
list2 = addHead(list2, 1);
//test deleteLast
cout << "List 1 contains: " << endl;
printAll(list1);
cout << "Deleting last node of List 1. Now contains: " << endl;
list1 = deleteLast(list1);
printAll(list1);
cout << "List 2 contains: " << endl;
printAll(list2);
//test append
cout << "Appending list 1 and list 2 yields: " << endl;
list3 = append(list1, list2);
printAll(list3);
//zip test
cout << "The zipped list of list 1 and list 2 is: " << endl;
list4 = zip(list1, list2);
printAll(list4);
//merge test
cout << "The merged list of list1 and list 2 is: " << endl;
list5 = merge(list1, list2);
printAll(list5);
return 0;
}
struct listNode *deleteLast(struct listNode *head) {
if (head == 0) {
return NULL;
} else if (head->next == 0) {
delete head;
return NULL;
} else {
head->next = deleteLast(head->next);
}
return head;
}
struct listNode * addHead(struct listNode *head, int k) {
listNode *nnode = new listNode;
nnode->info = k;
nnode->next = head;
return nnode;
}
void printAll(listNode *head) {
if (head == 0) {
cout << endl;
} else {
cout << head->info << "->";
printAll(head->next);
}
}
struct listNode * append(struct listNode *ahead,struct listNode *bhead) {
if (bhead == 0) {
return ahead;
} else if (ahead == 0) {
return bhead;
} else {
ahead->next = append(ahead->next, bhead);
}
return ahead;
}
struct listNode * zip(struct listNode *a, struct listNode *b)
{
if (b == 0) {
return 0;
} else {
listNode *tmp = a->next;
a->next = b;
a->next = zip(b, tmp);
}
return a;
}
struct listNode *merge(struct listNode *a, struct listNode *b)
{
listNode *result = NULL;
if (a == NULL)
return b;
else if (b == NULL)
return a;
if (a->info < b->info) {
result = a;
result->next = merge(a->next, b);
} else {
result = b;
result -> next = merge(a, b->next);
}
return result;
}
现在它就是不能正常工作。我陷入了一个无限循环,然后出现了分段错误。有人能告诉我我做错了什么吗?
我会给你一个提示。尝试删除代码中看似正常的部分,即append和zip函数。只需在它们周围放置一个注释块,然后重新运行程序。您将看到它按预期工作。
这里的问题是如何实现这些功能。在所有情况下,您都将指针传递给listNode,而不是副本或其他任何东西。在这种情况下,您对传递的指针所指向的对象所做的所有更改都将反映在未来对任何其他函数的调用中。因此,当您创建list3和list4时,您正在积极修改当前存在的list1和list2。它们不是独立的列表,它们都是使用指针语义创建的。
因此,list2的第一个元素指向list1。如果您想查看证明,请在执行zip()
或append()
之后,在list1和list2上使用printAll()
!
指针可能会导致许多看起来非常不寻常的问题,但只要您意识到指针是而不是对象本身,而是一个碰巧存储对象地址的单独值,您就可以看到对指向的对象进行修改会如何导致函数外的状态更改。
相关文章:
- C 中的排序列表
- 使用霍尔分区方案的快速排序算法返回原始未排序列表
- 带有额外参数的排序列表以进行比较功能
- 算法,用于查找获取排序列表所需的最小移动元素到结束步骤
- 迭代排序列表并计算不同的数字
- 维护多集中数字的排序列表和另一个集合中的累积总和
- 超过合并 k 排序列表的时间限制(leetcode)
- 正在检查排序列表中是否有一个范围内的数字
- O(N) 查找,但在排序列表上使用 upper_bound 时进行 O(log(N)) 比较
- 如何在只更改一个元素的情况下在排序列表中进行快速排序
- 返回指向排序列表的指针;C++中的链表
- 除了显示平均,最高和最低温度之外,有没有办法打印出整个排序列表
- 整数排序列表..TMP
- c++排序:具有相同数组值的排序列表
- 复制C++中未排序列表的构造函数
- 如何将元素添加到排序列表中..?(C++)
- 三维对象的Z排序列表
- 在我的排序列表中插入项目时出现问题
- 将节点插入到不带头指针的排序列表中
- 使用"pop_front"从排序列表中删除元素会导致崩溃