Вот моя программа для сворачивания связанного списка с использованием стека:

    public Node middle(Node head) {
            Node slow = head;
            Node fast = head;
            while (fast != null && fast.next != null) {
                fast = fast.next.next;
                slow = slow.next;
            }
            return slow;
        }

        public Node foldList(Node head){
            Node mid = middle(head);
            Node f = mid.next;
            Stack<Node> stacks = new Stack<>();
            if (head == null) return head;
            while (f != null){
                stacks.push(f);
                f = f.next;
            }
            Node temp = head;
            Node forv = head.next;
            while(!stacks.isEmpty()) {
                temp.next = stacks.pop();
                temp = temp.next;
                temp.next = forv;
                temp = temp.next;
                forv = forv.next;
            }
            return head;
        }

Вот код методов middle() и foldList(). Когда я запускаю его, он застревает в бесконечном цикле. Может ли кто-нибудь помочь мне узнать, почему это происходит?

0
nishchay007 26 Янв 2022 в 13:51
Что такое «свернуть связанный список»? Что такое «сухой ход»?
 – 
Adriaan Koster
26 Янв 2022 в 13:55
Если foldList вызывается с head == null, вы получите NullPointerException при ссылке на mid.next(). Таким образом, условие if(head == null) несколькими строками ниже никогда не будет выполнено. Я думаю, вы должны переместить это условие в первую строку foldList.
 – 
Adriaan Koster
26 Янв 2022 в 13:57
Итак, фолд: 1-2-3-4-5-6 становится 1-6-2-5-3-4?
 – 
Adriaan Koster
26 Янв 2022 в 14:01
Спасибо за помощь. да, складывание связанного списка - это то же самое, как вы догадываетесь.
 – 
nishchay007
26 Янв 2022 в 15:04

1 ответ

Лучший ответ

Проблема в том, что вы делаете это:

linked list: 1-2-3-4-5-6

Положите вторую половину в стопку:

linked list: 1-2-3-4-5-6
stack: 5-6    

Вставьте узлы стека между узлами связанного списка:

linked list: 1-6-2-3-4-5-6-2-3-4-5-6-2-3-4-5-6.....infinite

Вам нужно удалить вторую половину узлов (те, которые помещены в стек) из связанного списка, прежде чем вы начнете сворачиваться.

Поскольку это связанный список, вы можете просто аннулировать mid.next:

   public Node foldList(Node head){
        Node mid = middle(head);
        Node f = mid.next;

        // remove the second half
        mid.next = null

        Stack<Node> stacks = new Stack<>();
        if (head == null) return head;
        while (f != null){
            stacks.push(f);
            f = f.next;
        }

Вот мой полный код, использующий Deque вместо Stack (потому что Stack старый и заплесневелый):

import java.util.ArrayDeque;
import java.util.Deque;

public class Folder {

    public static void main(String[] args) {
        Node head = new Node(1);
        Node current = head;
        for (int i = 2; i < 7; i++) {
            current.next = new Node(i);
            current = current.next;
        }
        foldList(head);
        print(head);
    }

    private static void print(Node node) {
        System.out.println(node);
        while (node.next != null) {
            node = node.next;
            System.out.println(node);
        }
    }

    public static void foldList(Node head) {
        if (head == null) {
            return;
        }
        Deque<Node> nodesToFold = getNodesToFold(head);
        Node current = head;
        Node successor = head.next;
        while (!nodesToFold.isEmpty()) {
            current.next = nodesToFold.pop();
            current = current.next;
            current.next = successor;
            current = current.next;
            successor = successor.next;
        }
    }

    private static Deque<Node> getNodesToFold(Node head) {
        Node middle = findMiddle(head);
        Node current = middle.next;
        middle.next = null;
        Deque<Node> nodesToFold = new ArrayDeque<>();
        while (current != null) {
            nodesToFold.push(current);
            current = current.next;
        }
        return nodesToFold;
    }

    public static Node findMiddle(Node head) {
        Node slow = head;
        Node fast = head;
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;
    }


    static class Node {
        public int value;

        public Node next;

        public Node(int value) {
            this.value = value;
        }

        @Override
        public String toString() {
            return String.format("Node{value=%d}", value);
        }

    }
}

Выход:

Node{value=1}
Node{value=6}
Node{value=2}
Node{value=5}
Node{value=3}
Node{value=4}
0
Adriaan Koster 26 Янв 2022 в 14:32
Большое спасибо за помощь. Всего одну строчку пришлось добавить mid.next = null . и проблема решена. спасибо за помощь.
 – 
nishchay007
26 Янв 2022 в 15:01