简体   繁体   English

如何在不使用内置类和方法的情况下,通过 Java 中链表的 k 个节点将元素向左和向右移动?

[英]How can I shift the elements to left and right by k nodes of Linked List in Java without using built in classes and methods?

How can I shift the elements to left and right by k nodes of Linked List in Java without using built in classes and methods?如何在不使用内置类和方法的情况下,通过 Java 中链表的 k 个节点将元素向左和向右移动? Input:A->B->C->D n=2(Shift to right by 2) Output:C->D->A->B输入:A->B->C->D n=2(右移2) 输出:C->D->A->B

 public static void shiftListRight(LinkedList linkedList, int n) 
    {
        if(head==null)
        {
            return null;
        }
        int k=1;
        LinkedList tail=head;
        while(tail.getNext()!=null)
        {
            ++k;
            tail=tail.getNext();
        }
        n%=k;
        if(n==0)
            return head;
        int stepsToNewHead= k-n;
        tail.setNext(head);
        List newTail = tail;
        while(stepsToNewHead-- >0)
        {
            newTail.setNext(newTail);
        }
        
        //Implement your code here   

    }
}

This is pretty simple algorithm, where you have to use three time for...each loop with swap method.这是一个非常简单的算法,您必须使用 3 次for...each带有swap方法的循环。 I give you example for an array and you can easily transform it to List .我给你一个array例子,你可以很容易地将它转换为List

// offs > 0 - shift to the right
public static void shift(int[] arr, int offs) {
    offs %= arr.length;
    offs = offs < 0 ? arr.length + offs : offs;

    for (int i = 0, j = arr.length - 1; i < j; i++, j--)
        swap(arr, i, j);
    for (int i = 0, j = offs - 1; i < j; i++, j--)
        swap(arr, i, j);
    for (int i = offs, j = arr.length - 1; i < j; i++, j--)
        swap(arr, i, j);
}

private static void swap(int[] arr, int i, int j) {
    int tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}

Output:输出:

int[] arr1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
System.out.println(Arrays.toString(arr1));  // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
shift(arr1, 3);
System.out.println(Arrays.toString(arr1));  // [7, 8, 9, 0, 1, 2, 3, 4, 5, 6]

System.out.println();

int[] arr2 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
System.out.println(Arrays.toString(arr2));  // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
shift(arr2, -3);
System.out.println(Arrays.toString(arr2));  // [3, 4, 5, 6, 7, 8, 9, 0, 1, 2]

According to the sample input and output in your question, I would say that you want to rotate the elements in your linked list and not shift them.根据您问题中的示例输入和输出,我会说您想旋转链表中的元素而不是移动它们。

Here is my implementation of the SO question entitled Java - “Rotating” Objects in A LinkedList - Is LinkedList.addLast(LinkedList.removeFirst()) Good Or Bad Programming?这是我对题为Java - “Rotating” Objects in A LinkedList - Is LinkedList.addLast(LinkedList.removeFirst()) Good or Bad Programming的 SO 问题的实现 In other words the code below shows methods addFirst() , addLast() , removeFirst() and removeLast() that are mentioned in that question.换句话说,下面的代码显示了该问题中提到的addFirst()addLast()removeFirst()removeLast()

public class LinkdLst {
    private ListNode  head;

    public void addFirst(ListNode node) {
        if (node != null) {
            if (head == null) {
                head = node;
            }
            else {
                node.setNext(head);
                head = node;
            }
        }
    }

    public void addLast(ListNode node) {
        if (node != null) {
            if (head == null) {
                head = node;
            }
            else {
                ListNode previous = head;
                ListNode current = head.getNext();
                while (current != null) {
                    previous = current;
                    current = current.getNext();
                }
                previous.setNext(node);
            }
        }
    }

    public ListNode removeFirst() {
        ListNode removed;
        if (head == null) {
            removed = null;
        }
        else {
            removed = head;
            head = head.getNext();
        }
        return removed;
    }

    public ListNode removeLast() {
        ListNode removed;
        if (head == null) {
            removed = null;
        }
        else {
            ListNode previous = null;
            ListNode current = head;
            while (current.getNext() != null) {
                previous = current;
                current = current.getNext();
            }
            removed = current;
            if (previous != null) {
                previous.setNext(null);
            }
            else {
                head = null;
            }
        }
        return removed;
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        ListNode current = head;
        while (current != null) {
            sb.append(current);
            current = current.getNext();
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        LinkdLst list = new LinkdLst();
        list.addLast(new ListNode('A'));
        list.addLast(new ListNode('B'));
        list.addLast(new ListNode('C'));
        list.addLast(new ListNode('D'));
        System.out.println(list);
        for (int i = 0; i < 2; i++) {
            list.addLast(list.removeFirst());
        }
        System.out.println(list);
        for (int i = 0; i < 2; i++) {
            list.addFirst(list.removeLast());
        }
        System.out.println(list);
    }
}

class ListNode {
    private char  data;
    private ListNode  next;

    public ListNode(char datum) {
        data = datum;
    }

    public ListNode getNext() {
        return next;
    }

    public void setNext(ListNode node) {
        next = node;
    }

    public String toString() {
        return String.format("%c-> ", data);
    }
}

First I create the list according to the sample in your question.首先,我根据您问题中的示例创建列表。 Then I rotate them by 2 to get the desired result also according to the sample in your question.然后我也根据您问题中的示例将它们旋转 2 以获得所需的结果。 Then I rotate the "rotated" list by 2 in the opposite direction which returns the "rotated" list to its original order.然后我以相反的方向将“旋转”列表旋转 2,这将“旋转”列表返回到其原始顺序。 Here is the output when running the above code.这是运行上述代码时的输出。

Note that the toString() methods in the above code are only for debugging purposes and are not part of the implemented solution.请注意,上述代码中的toString()方法仅用于调试目的,而不是已实现的解决方案的一部分。 In other words, you can safely remove them.换句话说,您可以安全地删除它们。

A-> B-> C-> D-> 
C-> D-> A-> B-> 
A-> B-> C-> D->

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM