使用迭代从链表向后打印字符串

Printing strings backwards from a linked list using iteration

本文关键字:打印 字符串 链表 迭代      更新时间:2023-10-16

我无法弄清楚使指针向后移动的代码。我有一个已经这样做的递归函数,但是我在创建一个迭代函数来做同样的事情时遇到了麻烦。

void print_list_backward(Node_ptr a_node)
{
//base case. If a_node is Null, then simply return.
if (a_node == NULL) {
return;
//recurisve case. cout the word follwed by the function call which prints 
//the next word in the list
} else {
print_list_backward(a_node->ptr_to_next_node);
cout << a_node->word << " ";
}
}
void print_backward(Node_ptr a_node)
{
while (a_node != NULL)
{
a_node = a_node->ptr_to_next_node;
cout << a_node->word << " ";
}
}

老实说,我在linkedlist中向后打印的实现是一种侥幸,但我只需要帮助让它向后打印。我知道指针从左向右移动,但我不知道如何让它从右向左移动。

我当前print_backward()输出是

Input: The quick brown fox
Output: brown quick The

编辑带主的整个代码 此链接包含所有代码,希望能添加一些视角。我问题的目的是找到一种方法来使用迭代在链表中向后打印,这似乎是不可能的?

我的项目的问题是

编写并测试函数的迭代(即非递归(版本 print_list_backward命名为 print_backward((

当你有单链表时,使用递归函数向后打印列表是最容易的。仅当您愿意将指针存储在另一个容器(如堆栈(中,然后从容器打印对象时,才可以使用迭代方法。您最终会在指针上迭代两次。

void print_backward(Node_ptr a_node)
{
std::stack<Node_ptr> nodes;
while (a_node != NULL)
{
nodes.push(a_node);
a_node = a_node->ptr_to_next_node;
}
while ( !nodes.empty() )
{
a_node = nodes.top();
nodes.pop();
cout << a_node->word << " ";
}
}

我将使用子函数:

void print_forward(Node_ptr a_node)
{
while (a_node != nullptr) {
std::cout << a_node->word << " ";
a_node = a_node->ptr_to_next_node;
}
}
Node_ptr reverse(Node_ptr a_node)
{
Node_ptr prev = nullptr;
while (a_node != nullptr) {
Node_ptr next = a_node->ptr_to_next_node;
a_node->ptr_to_next_node = prev;
prev = a_node
a_node = next;
}
return prev;
}
void print_backward(Node_ptr a_node)
{
// Warning mutate list even if restored afterwards.
a_node = reverse(a_node);
print_forward(a_node);
a_node = reverse(a_node);
}

这有点好笑,通常困难的部分是递归实现。

好了,回到你的问题。如果你想迭代地做,问题是,...你不能。至少,如果您使用的是单链列表。正如你所说,指针从左向右移动。您还可以将每个节点存储在堆栈中,并在打印单词时弹出它们。但是伙计,...你不想那样做...不是因为它很复杂,因为它根本不复杂,而是因为它看起来很糟糕。

解决问题的一种方法是使用双链列表,而您可以完全控制列表中每个节点的方向。您可以从左到右以及从右到左移动。

您可以将列表的最后一个节点作为参数发送到函数print_backward,然后从右向左移动。

您可以选择两种方法:

反向复制

简而言之,创建链表的副本,允许您以相反的顺序迭代。 您可以通过堆栈(如其他答案所建议的那样(、新向量,甚至是相反顺序的新链表来做到这一点。

这种方法为您提供了时间和空间的复杂性O(n)

使用向量(伪代码(的示例:

vector<Node_ptr> temp_vector;
Node_ptr current_node = head;
while (current_node != nullptr) {
temp_vector.push_back(current_node);
current_node = current_node.next();
}
foreach node_ptr in (temp_vector.rbegin() to temp_vector.rend()) {
print node_ptr;
}

无副本

如果你不被允许保留链表的副本,那么你可以使用这种方法,它给你O(1(空间复杂度,但O(n^2(时间复杂度

伪代码:

Node_ptr current_node = get_last_node(head);
do {
print current_node;
current_node = find_previous(head, current_node);
} while (current_node != head)

get_last_node()的实施应该非常直接。 交给你。

find_previous看起来像这样:

Node_ptr find_previous(Node_ptr head, Node_ptr node) {
Node_ptr current_node = head;
while (current_node->next() != node) { }
return current_node;
}