wjffffff
wjffffff

Reputation: 1

How to "print list from tail to head" recursively?

I'm trying to print each node in a linked list from tail to head using recursion. But why I can't use the highlighting code to realize a recursion?

class Solution {
public:
    vector<int> printListFromTailToHead(ListNode* head) {
        if(!head)
        {
            vector<int> a(0);
            return a;
        }
        else if(!head -> next)
        {
            vector<int> a(1, head -> val);
            return a;
        }
        else
/*
            return printListFromTailToHead(head -> next).push_back(head -> val);
*/
    }
};

Upvotes: 0

Views: 711

Answers (4)

2785528
2785528

Reputation: 5566

I'm trying to print each node in a linked list from tail to head using recursion

Because you provide no info about your list, here I will show you a simple implementation of your desired function(s) using a "std::list". Note that the recursion I provide has no function parameters, no global scope vars, and no static vars (and I use cout, not print).

Also, I use a class form known as a Functor. I recommend them for encapsulating 'small' function(s). Please review literature on functors ... I consider them 'simpler' than the typical class.

#include <iostream>
using std::cout, std::cerr, std::endl, std::flush; // c++17
using std::ostream;

#include <list>
using std::list;

#include <string>
using std::string, std::to_string;



// typedefs are often simpler to read
// user typedefs ---------------vvvvvvvvvvv
typedef list<string>            StrList_t;
typedef list<string>::iterator  StrListIt_t;


// Functor
class F820_Recursive_t
{
   // data attributes of class instance are not global nor static vars
   StrList_t    m_strList;
   StrListIt_t  m_it;

public:
   int operator()() { return exec();  }  // Functor entry

private:

   int exec() // builds and modifies a std::list<string>
      {
         // example: using initializer list syntax
         m_strList = StrList_t { "111", "222", "333", "444", "555", "666", "777", "888" };

         recurseAndReportSize();

         // example: appending to existing list
         for (int i=301; i<309; ++i) {
            string s = "S" + to_string(i);
            m_strList.push_back (s);
         }

         recurseAndReportSize();

         cout << "\n  version cplusplus: " <<  __cplusplus  << "\n\n" << endl;
         return 0;
      }

   void recurseAndReportSize()
      {
         if (0 == m_strList.size()) {
            cout << "\n  empty  list" << flush;
            return;
         }

         cout << "\n\n  recurse over list to count elements ... " << flush;

         m_it = m_strList.begin(); // head to tail
         uint count = recurseCount();

         // report
         cout << count << " elements" << endl;

         // report list contents head to tail
         m_it = m_strList.begin();
         cout << "\n  Head to Tail recursive content report "
              << "\n  [" << coutListFromHeadToTail() << "]" << endl;

         // report list contents  tail to head
         m_it = m_strList.end(); m_it--;
         cout << "\n  Tail to Head recursive content report: "
              << "\n  [" << coutListFromTailToHead() << "]" << endl;
      }

   // recurse with no parameters, no static vars, no global vars
   uint recurseCount( )
      {  //        --^-- no parameters
         if (m_it == m_strList.end()) // RTC (recursion termination clause)
            return 0;

         m_it++; // step to next element

         return (1 + recurseCount()); // tail recursion
      }

   // recurse with no parameters, no static vars, no global vars
   string  coutListFromHeadToTail ( )
      {                        // --^-- no parameters
         cout << *m_it++;
         if (m_it == m_strList.end()) // RTC (recursion termination clause)
            return "";
         cout << ", ";
         return coutListFromHeadToTail(); // tail recursion
      }

   // recurse with no parameters, no static vars, no global vars
   string  coutListFromTailToHead ( )
      {                       // --^-- no parameters
         if (m_it == m_strList.begin()) {
            cout << *m_it;
            return "";
         }
         cout << *m_it << ", ";
         m_it--;
         return coutListFromTailToHead();  // tail recursion
      }

}; // class F820_Recursion_t

int main(int, char**) { return F820_Recursive_t()(); }

Output on my Lubuntu 19.04, g++ v8.3

  recurse over list to count elements ... 8 elements

  Head to Tail recursive content report 
  [111, 222, 333, 444, 555, 666, 777, 888]

  Tail to Head recursive content report: 
  [888, 777, 666, 555, 444, 333, 222, 111]


  recurse over list to count elements ... 16 elements

  Head to Tail recursive content report 
  [111, 222, 333, 444, 555, 666, 777, 888, S301, S302, S303, S304, S305, S306, S307, S308]

  Tail to Head recursive content report: 
  [S308, S307, S306, S305, S304, S303, S302, S301, 888, 777, 666, 555, 444, 333, 222, 111]

  version cplusplus: 201703

Upvotes: 0

molbdnilo
molbdnilo

Reputation: 66459

If you want to print, then print - don't build a vector.

void printListFromTailToHead(ListNode* head) 
{
    if (head)
    {
        printListFromTailToHead(head->next);
        std::cout << head->val << '\n';
    }
}

If you actually don't want to print anything but produce a vector, you need to rearrange the code a little bit, because push_back does not return anything:

vector<int> reverse_list(ListNode* head) 
{
    if (!head)
    {
        return vector<int>{};
    }
    else // You don't need a special case for a one-element list.
    {
        vector<int> ls = reverse_list(head->next);
        ls.push_back(head->val);
        return ls; 
    }
}

Upvotes: 2

Esdras Xavier
Esdras Xavier

Reputation: 863

Check out this solution, maybe isn't the better way to do it, but you maybe can take the idea. The thing is, you do not need return an array, also I did not get it why are you returning an vector, you could just call the function again and then print it like the code bellow.

#include <iostream>


using namespace std;


class ListNode {

public:
  ListNode *next;
  int value;

  ListNode() {
    this->next = NULL;
    this->value = 0;
  }

  ListNode(int _v) {
    this->next = NULL;
    this->value = _v;
  }
};

void printListNodeFromTailToHead(ListNode *node) {
  // If the current node is null will
  // exit the recursive function
  if (node == NULL) return ;

  // Else will call the function again with next ListNode
  // and print the current value

  printListNodeFromTailToHead(node->next);
  cout << node->value << endl;
}


int main() {
  ListNode *a = new ListNode(1);
  ListNode *tmp = a;

  for (int i = 2; i < 10; i++) {
    a->next = new ListNode(i);
    a = a->next;
  }

  printListNodeFromTailToHead(tmp);
  return 0;
}

Upvotes: 0

Vlad from Moscow
Vlad from Moscow

Reputation: 311088

Your function outputs nothing. And it is a bad idea to use a vector to output recursively a list.

The function can look for example the following way as it is shown in a demonstrative program below.

#include <iostream>

struct ListNode
{
    int value;
    ListNode *next;
};

void push_front( ListNode * &head, int value )
{
    head = new ListNode { value, head };
}

std::ostream & printListFromHeadToTail( ListNode * &head, std::ostream &os = std::cout  )
{
    return head == nullptr ? os 
                           : ( os << head->value << ' ', printListFromHeadToTail( head->next, os )  );  
}

std::ostream & printListFromTailToHead( ListNode * &head, std::ostream &os = std::cout  )
{
    return head == nullptr ? os 
                           : ( printListFromTailToHead( head->next, os ), os << head->value << ' ' );  
}

int main() 
{
    const int N = 10;
    ListNode *head = nullptr;

    for ( int i = 0; i < N; i++ ) push_front( head, i );

    printListFromHeadToTail( head ) << '\n';
    printListFromTailToHead( head ) << '\n';

    return 0;
}

Its output is

9 8 7 6 5 4 3 2 1 0 
0 1 2 3 4 5 6 7 8 9 

Upvotes: 0

Related Questions