0

I've created a very simple linked list in Java:

public class LinkedList {
    class Node {
        public Node next;
        public int item;

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

    int listSize = 0;
    Node first = null;
    Node last = null;

    public void add(int n) {
        Node node = new Node(n);
        if (first == null) {
            first = node;
        } else {
            last.next = node;
        }
        last = node;
        listSize++;
    }
}

So in the main class, I'll be adding elements to the linked list in a random order. But how can I create a method that counts the number of inversions in the linked-list?

So far, I've managed to achieve it with O(N^2) running time:

    public int inversionCount() {
        int count = 0;
        Node current = this.first;
        for (int i = 0; i <= this.listSize - 2; i++) {
            Node next = current.next;
            for (int j = i + 1; j < this.listSize; j++) {
                if (current.item > next.item) {
                    System.out.print("(" + current.item + "," + next.item + ")" + " ");
                    count += 1;
                }
                next = next.next;
            }
            current = current.next;
        }
        return count;
    }

However, as I said, the running time for this algorithm is O(N^2). I'm trying to achieve a running time of O(NlogN). How can this be achieved?

diginoise
  • 7,352
  • 2
  • 31
  • 39
TheSaviour
  • 61
  • 1
  • 7
  • If you have the list sorted as list of (value, original index) - O(N log N). Then the index and original index might have a mathematical relation with the inversion count. Or such. Happy puzzling. If fact the sorting algorithm itself could count the inversions in a parallel array inversion counts. – Joop Eggen Sep 19 '17 at 10:49
  • In your `add` method, shouldn't `last.next = Node;` be `first.next = Node;`? – OldCurmudgeon Sep 19 '17 at 10:51

2 Answers2

0

You are using bubble sort which has complexity of O(n^2)

For linked list the algorithm which is applicable with complexity of O(n log n) is Merge Sort.

Please see this walk trough of merge sort for linked lists

diginoise
  • 7,352
  • 2
  • 31
  • 39
  • I tried adding a slight modification to the code in the link: `if (a.item <= b.item) { result = a; result.next = sortedMerge(a.next, b); } else if (a.item > b.item) { result = b; invCount++; result.next = sortedMerge(a, b.next); }` I was hoping that it invCount would increment by 1 if a.item < b.item. Unfortunately, I didn't get the result I hoped for. – TheSaviour Sep 19 '17 at 11:40
  • hard to see without the full implementation, but per your code in aboce comment `invCount++` would not be executed when `a.item < b.item` as you increase it when `a.item > b.item` – diginoise Sep 19 '17 at 11:47
  • That's the idea. If the value in the left sub-linked-list is greater than the value in the right sub-linked-list, then invCount should increment by 1. But when I tested it out, it doesn't calculate the correct number of inversions – TheSaviour Sep 19 '17 at 14:11
  • ... in other words in the code in your 1st comment, increment of `invCount` happens only when `a.item > b.item` so you codded the opposite of what you expect to happen OR you have misstyped the 1st comment. – diginoise Sep 19 '17 at 14:19
  • @TheSaviour, your idea is good for counting the inversions in sortedMerge() but you must also count the inversions in merge(). [Here](https://www.geeksforgeeks.org/inversion-count-in-array-using-merge-sort/) is an explanation for arrays. With linked lists it's a little more complex but the idea is the same. You need to know how many items are in the left list ("len"), which yo can do by passing a parameter to merge or calculating it. Then for each item "i" in the left list greater than the corresponding item in the right list j, increment inversions by len - i – Marcel Dec 24 '22 at 17:58
0

In insertion sort it would take o(n) on a normal array as even if you use binary search to find where the element needs to be sorted it would take o(n) to make new space for the array. In a linked list, it takes o(1) to insert and with binary search, you can get a complexity of o(nlogn). From there you can count the inversions of this array by counting the calculation of the index to move minus the previous index. Add all of these calculations up every time to get the number inversions.

OMG mems
  • 11
  • 3