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

时间:2017-08-07 01:11:14

标签: c++ string recursion linked-list nodes

我无法弄清楚代码以使指针向后移动。我有一个已经执行此操作的递归函数,但是我无法创建迭代函数来执行相同的操作。

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 << " ";
  }
}

老实说,我在链接列表中向后打印的实现有点像侥幸,但我只是需要帮助才能让它倒退。我知道指针从左向右移动,但我不知道如何让它从右向左移动。

print_backward()的当前输出是

Input: The quick brown fox
Output: brown quick The

编辑 Entire code w/ main此链接包含所有代码,应该有希望添加一些观点。我的问题的目的是找到一种方法来使用迭代在链表中向后打印,这似乎是不可能的?

我的项目的问题是

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

4 个答案:

答案 0 :(得分:1)

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

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 << " ";
   }
}

答案 1 :(得分:1)

我将使用子功能:

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);
}

答案 2 :(得分:0)

它有点滑稽,通常很难实现的是递归实现。

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

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

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

答案 3 :(得分:0)

您可以选择两种方法:

反向复制

简而言之,创建链表的副本,允许您以相反的顺序迭代。您可以通过堆栈(如其他答案所示),新向量,甚至是相反顺序的新链接列表来执行此操作。

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

使用vector(伪代码)的例子:

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;
}