简体   繁体   中英

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? Input:A->B->C->D n=2(Shift to right by 2) Output: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. I give you example for an array and you can easily transform it to 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? In other words the code below shows methods addFirst() , addLast() , removeFirst() and removeLast() that are mentioned in that question.

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. Then I rotate the "rotated" list by 2 in the opposite direction which returns the "rotated" list to its original order. 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. In other words, you can safely remove them.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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