我正在尝试使用C ++来反转链接列表,然后打印出反向链接列表。
例如: 原始列表是1-> 2-> 3 回复后:3-> 2-> 1
但是当我试图打印出反向链表时,3-> 2-> 1成为圆形链表,如3< - > 2
以下是我的代码:
#include <iostream>
#include <sstream>
using namespace std;
class List{
public:
int value;
List *next;
List(int);
List(int, List *);
};
List::List(int v){
value = v;
next = NULL;
}
List::List(int v, List *ne){
value = v;
next = ne;
}
string IntToString(int val){
stringstream temp;
temp<<val;
return temp.str();
}
void print(List *l){
string output= "";
while(l->next != NULL){
output+=(IntToString(l->value)+"-->");
l = l->next;
}
output+=(IntToString(l->value)+"-->NULL");
cout<<output<<endl;
}
List reverse(List L){
if(L.next == NULL) return L;
List remain = reverse(*(L.next));
List *current = &remain;
while(current->next != NULL)
current = (current->next);
L.next = NULL;
current->next = &L;
//print(remain);
return remain;
}
List copy(List l){
return l;
}
int main() {
List L3(3);
List L2(2, &L3);
List L1(1, &L2);
List L4 = reverse(L1);
print(&L4);
return 0;
}
谁能告诉我为什么会这样?非常感谢!
答案 0 :(得分:0)
我认为您的反向算法是正确的,但remain
是一个局部变量,返回后无效,因此L4将包含无效指针。更改reverse()
的签名以获取并返回List *
。
List *reverse(List *L){ if(L->next == NULL) return L; List *remain = reverse(L->next); List *current = remain; while(current->next != NULL) current = (current->next); L->next = NULL; current->next = L; //print(remain); return remain; }
答案 1 :(得分:0)
只需查看您正在堆栈中创建名为reverse()
的{{1}}函数,并将其插入列表中。这不起作用:从函数返回后,此对象将超出范围(remain
中的原始对象具有相同的问题但您在离开main()
后不尝试使用它们)。此外,您的main()
函数似乎具有二次性能,而它应该是线性的。我认为这样的事情可以解决问题:
reverse()
上述实现也避免了递归。
答案 2 :(得分:0)
首先,我想指出,包含list
指针的another list
在概念上是错误的。
单独创建一个列表节点类,例如
struct ListNode {
int value;
Node *next;
};
然后你的List
变为,
class List {
...
ListNode *head;
...
};
现在转向逆转。在方法List reverse( List L )
中, L只是一个局部变量 。 在,
return remain;
} // Here the scope of L ends
因此,返回List
的{{1}}值为L的位置
next
这会在您的实施中导致 未定义的行为 。
编辑:我有空闲时间,所以我想出了this implementation。它使用相同的算法,但修改了调用它的原始列表。