c++data-structureslinked-listsingly-linked-listreorderlist

C++ reordering Singly Linked List


Hi I'm trying to write a code for singly linked list that reorders the nodes so that:

L1->L2->L3->...->Ln to L1->Ln->L2->Ln-1->L3->Ln-2...

So I tried to do this by finding the node at the end of the list and setting that node as the next of current node and then finishing the loop by setting the current node as the next next of current node.

#include <cstdlib>
#include <iostream>

using namespace std;

struct ListNode {
        int val;
        ListNode *next;
        ListNode() : val(0), next(nullptr) {}
        ListNode(int x) : val(x), next(nullptr) {}
        ListNode(int x, ListNode *next) : val(x), next(next) {}
};

ListNode* newNode(int x){
    ListNode* temp = new ListNode;
    temp->val = x;
    temp->next = NULL;
    return temp;
}

void printlist(ListNode* head)
{
    while (head != NULL) {
        cout << head->val << " ";
        if (head->next)
            cout << "-> ";
        head = head->next;
    }
    cout << endl;
}

void reorderList(ListNode* head){
    ListNode *curr = head;
    ListNode *temp=head;
    ListNode *last=NULL;
    while(curr->next != NULL){
        while(temp->next != NULL){
            temp=temp->next;
            last=temp;
        }
        curr->next=last;
        last->next=curr->next->next;
        curr=curr->next->next;
        temp=curr->next;
    }
}

int main(int argc, char** argv) {
    ListNode* head = newNode(1);
    head->next = newNode(2);
    head->next->next = newNode(3);
    head->next->next->next = newNode(4);
    head->next->next->next->next = newNode(5);
 
    printlist(head); // Print original list
    reorderList(head); // Modify the list
    printlist(head); // Print modified list

    return 0;
}

So far, after displaying the original list, the program stops by saying that the run failed. I'm having some problem understanding the singly linked list and I don't know what I'm doing wrong.


Solution

  • I have modified your code to show a correct answer:

    #include <iostream>
    
    struct ListNode
    {
      int val;
      ListNode* next;
      ListNode(): val( 0 ), next( nullptr ) {}
      ListNode( int x ): val( x ), next( nullptr ) {}
      ListNode( int x, ListNode* next ): val( x ), next( next ) {}
    };
    
    void printlist( ListNode* head )
    {
      while( head != nullptr ) {
        std::cout << head->val << " ";
        if( head->next )
          std::cout << "-> ";
        head = head->next;
      }
      std::cout << std::endl;
    }
    
    void reorderList( ListNode* head ) {
      ListNode* pf = head;
      ListNode* pt = nullptr;
      ListNode* tmp = nullptr;
      while( true )
      {
        // find n-1 node
        tmp = pf;
        while( tmp && tmp->next && tmp->next->next )
          tmp = tmp->next;
        // check to see n-1 node is not equal to the first node
        if( tmp == pf )
          break;
        // reorder
        pt = tmp;
        tmp = pf->next;
        pf->next = pt->next;
        pt->next->next = tmp;
        pf = tmp;
        pt->next = nullptr;
      }
    }
    
    int main( int argc, char** argv ) {
      ListNode* head = new ListNode( 1 ); 
      head->next = new ListNode( 2 );
      head->next->next = new ListNode( 3 );
      head->next->next->next = new ListNode( 4 );
      head->next->next->next->next = new ListNode( 5 );
      head->next->next->next->next->next = new ListNode( 6 );
      printlist( head ); // Print original list
      reorderList( head ); // Modify the list
      printlist( head ); // Print modified list
    
      return 0;
    }
    

    and the result is like below:

    1 -> 2 -> 3 -> 4 -> 5 -> 6                                                                                              
    1 -> 6 -> 2 -> 5 -> 3 -> 4