web-dev-qa-db-fra.com

Reverse Singly Linked List Java

Quelqu'un peut-il me dire pourquoi mon doseur de code fonctionne? Je veux inverser une seule liste chaînée en Java: c'est la méthode (qui ne fonctionne pas correctement)

public void reverseList(){
    Node before = null;
    Node tmp = head;
    Node next = tmp.next;
    while(tmp != null){
      if(next == null)
         return;
      tmp.next = before;
      before = tmp;
      tmp = next;
      next = next.next;
    }
}

Et voici la classe Node:

public class Node{
   public int data;
   public Node next;
   public Node(int data, Node next){
      this.data = data;
      this.next = next;
   }
}

Sur l'entrée 4-> 3-> 2-> 1, j'ai obtenu la sortie 4. Je l'ai déboguée et les pointeurs sont réglés correctement, mais je ne comprends toujours pas pourquoi il n'affiche que 4.

27
sammy333
Node next = tmp.next;
while(tmp != null){

Alors que se passe-t-il quand tmp == null?

Vous l'avez presque, cependant.

Node before = null;
Node tmp = head;
while (tmp != null) {
    Node next = tmp.next;
    tmp.next = before;
    before = tmp;
    tmp = next;
}
head = before;

Ou en nommant plus gentiment (?):

Node reversedPart = null;
Node current = head;
while (current != null) {
    Node next = current.next;
    current.next = reversedPart;
    reversedPart = current;
    current = next;
}
head = reversedPart;

Art ASCII:

        <__<__<__ __ : reversedPart    : head
                 (__)__ __ __
head :   current:      >  >  >
79
Joop Eggen
public Node<E> reverseList(Node<E> node) {
    if (node == null || node.next == null) {
        return node;
    }
    Node<E> currentNode = node;
    Node<E> previousNode = null;
    Node<E> nextNode = null;

    while (currentNode != null) {
        nextNode = currentNode.next;
        currentNode.next = previousNode;
        previousNode = currentNode;
        currentNode = nextNode;
    }
    return previousNode;
}
18
Ranjeet

Si ce n'est pas un devoir et que vous le faites "manuellement" exprès, alors je vous recommande d'utiliser

Collections.reverse(list);

Collections.reverse () est annulé et votre liste est inversée après l'appel.

7
Oliver Hausler

La méthode pour inverser une liste chaînée est la suivante.

Méthode inverse

public void reverseList() {
    Node<E> curr = head;
    Node<E> pre = null;
    Node<E> incoming = null;

    while(curr != null) {
        incoming = curr.next;   // store incoming item

        curr.next = pre;        // swap nodes
        pre = curr;             // increment also pre

        curr = incoming;        // increment current
    }

    head = pre; // pre is the latest item where
                // curr is null
}

Trois références sont nécessaires pour inverser une liste: pre , curr , incoming

...      pre     curr    incoming
... --> (n-1) --> (n) --> (n+1) --> ...

Pour inverser un nœud, vous devez stocker l’élément pre vious, afin de pouvoir utiliser le statut simple;

curr.next = pre;

Pour inverser la direction de l'élément en cours. Cependant, pour parcourir la liste, vous devez stocker l'élément entrant avant l'exécution de l'instruction ci-dessus, car pour inverser la référence suivante de l'élément actuel, vous ne connaissez plus l'élément entrant, c'est pourquoi une troisième référence est nécessaire.

Le code de démonstration est comme ci-dessous;

Classe d'échantillon LinkedList

public class LinkedList<E> {

    protected Node<E> head;

    public LinkedList() {
        head = null;
    }

    public LinkedList(E[] list) {
        this();
        addAll(list);
    }

    public void addAll(E[] list) {
        for(int i = 0; i < list.length; i++)
            add(list[i]);
    }

    public void add(E e) {
        if(head == null)
            head = new Node<E>(e);
        else {
            Node<E> temp = head;

            while(temp.next != null)
                temp = temp.next;

            temp.next = new Node<E>(e);
        }
    }

    public void reverseList() {
        Node<E> curr = head;
        Node<E> pre = null;
        Node<E> incoming = null;

        while(curr != null) {
            incoming = curr.next;   // store incoming item

            curr.next = pre;        // swap nodes
            pre = curr;             // increment also pre

            curr = incoming;        // increment current
        }

        head = pre; // pre is the latest item where
                    // curr is null
    }

    public void printList() {
        Node<E> temp = head;

        System.out.print("List: ");
        while(temp != null) {
            System.out.print(temp + " ");
            temp = temp.next;
        }

        System.out.println();
    }

    public static class Node<E> {

        protected E e;
        protected Node<E> next;

        public Node(E e) {
            this.e = e;
            this.next = null;
        }

        @Override
        public String toString() {
            return e.toString();
        }

    }

}

Code de test

public class ReverseLinkedList {

    public static void main(String[] args) {
        Integer[] list = { 4, 3, 2, 1 };

        LinkedList<Integer> linkedList = new LinkedList<Integer>(list);

        linkedList.printList();
        linkedList.reverseList();
        linkedList.printList();
    }

}

Sortie

List: 4 3 2 1 
List: 1 2 3 4 
7
Levent Divilioglu

Nous pouvons avoir trois nœuds précédent, actuel et suivant.

public void reverseLinkedlist()
{
    /*
     * Have three nodes i.e previousNode,currentNode and nextNode
 When currentNode is starting node, then previousNode will be null
 Assign currentNode.next to previousNode to reverse the link.
 In each iteration move currentNode and previousNode by  1 node.
     */

    Node previousNode = null;
    Node currentNode = head;
    while (currentNode != null) 
    {
        Node nextNode = currentNode.next;
        currentNode.next = previousNode;
        previousNode = currentNode;
        currentNode = nextNode;
    }
    head = previousNode;
}
public void reverse() {
    Node prev = null; Node current = head; Node next = current.next;
    while(current.next != null) {
        current.next = prev;
        prev = current;
        current = next;
        next = current.next;
    }
    current.next = prev;
    head = current;
}
2
Sean Paul

Une solution plus élégante consisterait à utiliser la récursivité

void ReverseList(ListNode current, ListNode previous) {
            if(current.Next != null) 
            {
                ReverseList(current.Next, current);
                ListNode temp = current.Next;
                temp.Next = current;
                current.Next = previous;
            }
        }
1
Shayno

Je sais que la solution récursive n'est pas optimale, mais je voulais juste en ajouter une ici:

public class LinkedListDemo {

    static class Node {
        int val;
        Node next;

        public Node(int val, Node next) {
            this.val = val;
            this.next = next;
        }

        @Override
        public String toString() {
            return "" + val;
        }
    }

    public static void main(String[] args) {
        Node n = new Node(1, new Node(2, new Node(3, new Node(20, null))));
        display(n);
        n = reverse(n);
        display(n);
    }

    static Node reverse(Node n) {
        Node tail = n;
        while (tail.next != null) {
            tail = tail.next;
        }
        reverseHelper(n);
        return (tail);
    }

    static Node reverseHelper(Node n) {
        if (n.next != null) {
            Node reverse = reverseHelper(n.next);
            reverse.next = n;
            n.next = null;
            return (n);
        }
        return (n);
    }

    static void display(Node n) {
        for (; n != null; n = n.next) {
            System.out.println(n);
        }
    }
}
1
Jose Cifuentes

Je ne comprends pas ... pourquoi ne pas faire ceci: 

private LinkedList reverseLinkedList(LinkedList originalList){
    LinkedList reversedList = new LinkedList<>();

    for(int i=0 ; i<originalList.size() ; i++){
        reversedList.add(0, originalList.get(i));
    }

    return reversedList;
}

Je trouve cela plus facile.

1
Manov

J'ai essayé le code ci-dessous et cela fonctionne bien:

Node head = firstNode;
Node current = head;
while(current != null && current.next != null){
    Node temp = current.next;
    current.next = temp.next;
    temp.next = head;
    head = temp;
}

Fondamentalement, un par un, il place le pointeur suivant d'un nœud sur son prochain nœud. Tous les nœuds sont donc attachés à la fin de la liste. 

1
shailendra1118
Node reverse_rec(Node start) {
    if (start == null || start -> next == null) {
       return start;
    }

    Node new_start = reverse(start->next);
    start->next->next = start;
    start->next = null;
    return new_start;
}


Node reverse(Node start) {
    Node cur = start;
    Node bef = null;

    while (cur != null) {
       Node nex = cur.next;
       cur.next = bef;
       bef = cur;
       cur = nex;
    }
    return bef;
}
1
user2547616
public class SinglyLinkedListImpl<T> {

    private Node<T> head;

    public void add(T element) {
        Node<T> item = new Node<T>(element);
        if (head == null) {
            head = item;
        } else {
            Node<T> temp = head;
            while (temp.next != null) {
                temp = temp.next;
            }
            temp.next = item;
        }
    }

    private void reverse() {

        Node<T> temp = null;
        Node<T> next = null;
        while (head != null) {
            next = head.next;
            head.next = temp;
            temp = head;
            head = next;
        }
        head = temp;
    }

    void printList(Node<T> node) {
        while (node != null) {
            System.out.print(node.data + " ");
            node = node.next;
        }
        System.out.println();
    }

    public static void main(String a[]) {
        SinglyLinkedListImpl<Integer> sl = new SinglyLinkedListImpl<Integer>();
        sl.add(1);
        sl.add(2);
        sl.add(3);
        sl.add(4);

        sl.printList(sl.head);
        sl.reverse();
        sl.printList(sl.head);

    }

    static class Node<T> {

        private T data;
        private Node<T> next;

        public Node(T data) {
            super();
            this.data = data;
        }

    }
}
0
Shivanshu

Utiliser la récursion, c'est trop facile:

package com.config;

import Java.util.Scanner;

public class Help {

    public static void main(String args[]){

        Scanner sc = new Scanner(System.in);
        Node head = null;
        Node temp = null;
        int choice = 0;
        boolean flage = true;
        do{
            Node node = new Node();
            System.out.println("Enter Node");
            node.data = sc.nextInt();
            if(flage){
                head = node;
                flage = false;
            }
            if(temp!=null)
                temp.next = node;
            temp = node;

            System.out.println("Enter 0 to exit.");
            choice = sc.nextInt();
        }while(choice!=0);

        Help.getAll(head);

        Node reverse = Help.reverse(head,null);
        //reverse = Help.reverse(head, null);

        Help.getAll(reverse);

    }

    public static void getAll(Node head){
        if(head==null)
            return ;
        System.out.println(head.data+"Memory Add "+head.hashCode());
        getAll(head.next);
    }

    public static Node reverse(Node head,Node tail){
        Node next = head.next;
        head.next = tail;
        return (next!=null? reverse(next,head) : head);
    }
}

class Node{
    int data = 0;
    Node next = null;
}
0
ritesh9984
/**
 * Reverse LinkedList
 * @author asharda
 *
 */

class Node
{
  int data;
  Node next;
  Node(int data)
  {
    this.data=data;
  }
}
public class ReverseLinkedList {

  static Node root;
  Node temp=null;
  public void insert(int data)
  {
    if(root==null)
    {
      root=new Node(data);

    }
    else
    {
      temp=root;
      while(temp.next!=null)
      {
        temp=temp.next;
      }

      Node newNode=new Node(data);
      temp.next=newNode;
    }
  }//end of insert

  public void display(Node head)
  {
    while(head!=null)
    {
      System.out.println(head.data);
      head=head.next;
    }

  }

  public Node reverseLinkedList(Node head)
  {
    Node newNode;
    Node tempr=null;
    while(head!=null)
    {
      newNode=new Node(head.data);
      newNode.next=tempr;
      tempr=newNode;
      head=head.next;
    }
    return tempr;
  }
  public static void main(String[] args) {

    ReverseLinkedList r=new ReverseLinkedList();
    r.insert(10);
    r.insert(20);
    r.insert(30);
    r.display(root);
    Node t=r.reverseLinkedList(root);
    r.display(t);
  }

}
0
user7258708
Node Reverse(Node head) {
        Node n,rev;
        rev = new Node();
        rev.data = head.data;
        rev.next = null;


        while(head.next != null){
            n = new Node();
            head = head.next;
            n.data = head.data;
            n.next = rev;
            rev = n;
            n=null;


        }
    return rev;
}

Utilisez la fonction ci-dessus pour inverser une liste liée unique.

0
Aditya Parmar
    // Java program for reversing the linked list
    class LinkedList {

        static Node head;

        static class Node {

            int data;
            Node next;

            Node(int d) {
                data = d;
                next = null;
            }
        }

      //  Function to reverse the linked list 
        Node reverse(Node node) {
            Node prev = null;
            Node current = node;
            Node next = null;
            while (current != null) {
                next = current.next;
                current.next = prev;
                prev = current;
                current = next;
            }
            node = prev;
            return node;
        }




        // prints content of double linked list
        void printList(Node node) {
            while (node != null) {
                System.out.print(node.data + " ");
                node = node.next;
            }
        }


        public static void main(String[] args) {
            LinkedList list = new LinkedList();
            list.head = new Node(85);
            list.head.next = new Node(15);
            list.head.next.next = new Node(4);
            list.head.next.next.next = new Node(20);

            System.out.println("Given Linked list");
            list.printList(head);
            head = list.reverse(head);
            System.out.println("");
            System.out.println("Reversed linked list ");
            list.printList(head);
        }
    }


OUTPUT: -

Given Linked list
85 15 4 20 
Reversed linked list 
20 4 15 85 
0
saurabh prakash

Pour inverser une liste chaînée, vous devez avoir trois nœuds, top , beforeTop et AfterTop . Top est l'en-tête de la liste des liens simples, par conséquent, beforeTop serait nul et afterTop serait le prochain élément de top et avec chaque itération, avancer beforeTop est attribué top et top est assigné afterTop (c.-à-d. top . suivant ).

private static Node inverse(Node top) {
        Node beforeTop=null, afterTop;
        while(top!=null){
            afterTop=top.next;
            top.next=beforeTop;
            beforeTop=top;
            top=afterTop;
        }
        return beforeTop;
    }
0
bpjoshi
public class ReverseLinkedList {

    public static void main(String args[]){
        LinkedList<String> linkedList = new LinkedList<String>();
        linkedList.add("a");
        linkedList.add("b");
        linkedList.add("c");
        linkedList.add("d");
        linkedList.add("e");
        linkedList.add("f");
        System.out.println("Original linkedList:");
        for(int i = 0; i <=linkedList.size()-1; i++){

            System.out.println(" - "+ linkedList.get(i));

        }
        LinkedList<String> reversedlinkedList = reverse(linkedList);
        System.out.println("Reversed linkedList:");
        for(int i = 0; i <=reversedlinkedList.size()-1; i++){
            System.out.println(" - "+ reversedlinkedList.get(i));

        }
    }

    public static LinkedList<String> reverse(LinkedList<String> linkedList){

        for(int i = 0; i < linkedList.size()/2; i++){
            String temp = linkedList.get(i);
            linkedList.set(i, linkedList.get(linkedList.size()-1-i));
            linkedList.set((linkedList.size()-1-i), temp);
        }
        return linkedList;
    }
}
0
 public ListNode reverseList(ListNode head) {
    ListNode prev = null;
    ListNode curr = head;
    while (curr != null) {
        ListNode nextTemp = curr.next;
        curr.next = prev;
        prev = curr;
        curr = nextTemp;
    }
    return prev;
}

vérifiez plus de détails sur l'analyse de la complexité http://javamicro.com/ref-card/DS-Algo/How-to-Reverse-Singly-Linked-List ?

0
jitendra
package LinkedList;

import Java.util.LinkedList;

public class LinkedListNode {

    private int value;
    private LinkedListNode next = null;

    public LinkedListNode(int i) {
        this.value = i;
    }

    public LinkedListNode addNode(int i) {
        this.next = new LinkedListNode(i);
        return next;
    }

    public LinkedListNode getNext() {
        return next;
    }

    @Override
    public String toString() {
        String restElement = value+"->";
        LinkedListNode newNext = getNext();
        while(newNext != null)
            {restElement = restElement + newNext.value + "->";
            newNext = newNext.getNext();}
        restElement = restElement +newNext;
        return restElement;
    }

    public static void main(String[] args) {
        LinkedListNode headnode = new LinkedListNode(1);
        headnode.addNode(2).addNode(3).addNode(4).addNode(5).addNode(6);

        System.out.println(headnode);
        headnode = reverse(null,headnode,headnode.getNext());

        System.out.println(headnode);
    }

    private static LinkedListNode reverse(LinkedListNode prev, LinkedListNode current, LinkedListNode next) {
        current.setNext(prev);
        if(next == null)
            return current;
         return reverse(current,next,next.getNext());   
    }

    private void setNext(LinkedListNode prev) {
        this.next = prev;
    }
}
0
user5807826

Vous pouvez aussi essayer ceci

    LinkedListNode pointer = head;
    LinkedListNode prev = null, curr = null;

    /* Pointer variable loops through the LL */
    while(pointer != null)
    {
        /* Proceed the pointer variable. Before that, store the current pointer. */
        curr = pointer; //          
        pointer = pointer.next;         

        /* Reverse the link */
        curr.next = prev;

        /* Current becomes previous for the next iteration */
        prev = curr;            
    }

    System.out.println(prev.printForward());
0
Sankalp
package com.three;

public class Link {

    int a;
    Link Next;

    public Link(int i){
        a=i;
    }

}

public class LinkList {

    Link First = null;

    public void insertFirst(int a){
        Link objLink = new Link(a);

        objLink.Next=First;
        First = objLink;

    }

    public void displayLink(){

        Link current = First;
        while(current!=null){
            System.out.println(current.a);
            current = current.Next;
        }

    }

    public void ReverseLink(){
        Link current = First;
        Link Previous = null;
        Link temp = null;

        while(current!=null){

            if(current==First)
                temp = current.Next;
            else
                temp=current.Next;

            if(temp==null){
                First = current;
                //return;
            }
            current.Next=Previous;
            Previous=current;
            //System.out.println(Previous);
            current = temp;
        }

    }

    public static void main(String args[]){

        LinkList objLinkList = new LinkList();
        objLinkList.insertFirst(1);
        objLinkList.insertFirst(2);
        objLinkList.insertFirst(3);
        objLinkList.insertFirst(4);
        objLinkList.insertFirst(5);
        objLinkList.insertFirst(6);
        objLinkList.insertFirst(7);
        objLinkList.insertFirst(8);
        objLinkList.displayLink();
        System.out.println("-----------------------------");
        objLinkList.ReverseLink();
        objLinkList.displayLink();

    }

}
0
prashant chaudhary

Utilisez ceci.

if (current== null || current.next==null) return current;
 Node nextItem = current.next;
 current.next = null;
 Node reverseRest = reverse(nextItem);
 nextItem.next = current;
 return reverseRest

ou Programme Java pour inverser une liste de liens simples

0
Shriram
public static LinkedList reverseLinkedList(LinkedList node) {
    if (node == null || node.getNext() == null) {
        return node;
    }

    LinkedList remaining = reverseLinkedList(node.getNext());
    node.getNext().setNext(node);
    node.setNext(null);
    return remaining;
}
0
Aman

Je pense que votre problème est que votre dernier élément ensuite attribut n’est pas modifié en raison de votre condition.

if(next == null)
     return;

Est au début de votre boucle.

Je le déplacerais juste après que tmp.next ait été assigné:

while(tmp != null){

  tmp.next = before;
  if(next == null)
     return;
  before = tmp;
  tmp = next;
  next = next.next;
}