views:

241

answers:

1

Hi I want to use merge sort for sorting my doubly linked list.I have created 3 classes(Node,DoublyLinkedList,MergeSort) but it will throw this exception for these lines:

1.in the getNodes method of DoublyLinkedList--->   throw new IndexOutOfBoundsException();
2.in the add method of DoublyLinkedList----->   Node cursor = getNodes(index);
3.in the sort method of MergeSort class------>    listTwo.add(x,localDoublyLinkedList.getValue(x));
4.in the main method of DoublyLinkedList----->merge.sort();

this is my Merge class:(I put the whole code for this class for beter understanding)

public class MergeSort {

private DoublyLinkedList localDoublyLinkedList;

public MergeSort(DoublyLinkedList list) {
    localDoublyLinkedList = list;

}

public void sort() {

    if (localDoublyLinkedList.size() <= 1) {
        return;
    }
    DoublyLinkedList listOne = new DoublyLinkedList();
    DoublyLinkedList listTwo = new DoublyLinkedList();
    for (int x = 0; x < (localDoublyLinkedList.size() / 2); x++) {
        listOne.add(x, localDoublyLinkedList.getValue(x));
    }
    for (int x = (localDoublyLinkedList.size() / 2) + 1; x < localDoublyLinkedList.size(); x++) {
        listTwo.add(x, localDoublyLinkedList.getValue(x));
    }
//Split the DoublyLinkedList again
        MergeSort sort1 = new MergeSort(listOne);
        MergeSort sort2 = new MergeSort(listTwo);
        sort1.sort();
        sort2.sort();

    merge(listOne, listTwo);
}

public void merge(DoublyLinkedList a, DoublyLinkedList b) {
    int x = 0;
    int y = 0;
    int z = 0;
    while (x < a.size() && y < b.size()) {
        if (a.getValue(x) < b.getValue(y)) {
            localDoublyLinkedList.add(z, a.getValue(x));
            x++;
        } else {
            localDoublyLinkedList.add(z, b.getValue(y));
            y++;
        }
        z++;
    }
    //copy remaining elements to the tail of a[];
    for (int i = x; i < a.size(); i++) {
        localDoublyLinkedList.add(z, a.getValue(i));
        z++;
    }

    for (int i = y; i < b.size(); i++) {
        localDoublyLinkedList.add(z, b.getValue(i));
        z++;
    }

}
}

and just a part of my DoublyLinkedList:

    private Node getNodes(int index) throws IndexOutOfBoundsException {
    if (index < 0 || index > length) {
        throw new IndexOutOfBoundsException();
    } else {
        Node cursor = head;
        for (int i = 0; i < index; i++) {
            cursor = cursor.getNext();
        }
        return cursor;
    }
}
  public void add(int index, int value) throws IndexOutOfBoundsException {
    Node cursor = getNodes(index);
    Node temp = new Node(value);
    temp.setPrev(cursor);
    temp.setNext(cursor.getNext());
    cursor.getNext().setPrev(temp);
    cursor.setNext(temp);
    length++;
}

    public static void main(String[] args) {
    int i = 0;
    i = getRandomNumber(10, 10000);
    DoublyLinkedList list = new DoublyLinkedList();
    for (int j = 0; j < i; j++) {
        list.add(j, getRandomNumber(10, 10000));
        MergeSort merge = new MergeSort(list);
        merge.sort();

        System.out.println(list.getValue(j));
    }
}

also thiese are the stacktrace:

run:
0
0
Exception in thread "main" java.lang.IndexOutOfBoundsException
    at datastructureproject.DoublyLinkedList.getNodes(DoublyLinkedList.java:57)
    at datastructureproject.DoublyLinkedList.add(DoublyLinkedList.java:34)
    at datastructureproject.MergeSort.sort(MergeSort.java:31)
    at datastructureproject.DoublyLinkedList.main(DoublyLinkedList.java:82)
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)

also when I debug:

debug:
0
0
Exception in thread "main" java.lang.IndexOutOfBoundsException
    at datastructureproject.DoublyLinkedList.getNodes(DoublyLinkedList.java:57)
    at datastructureproject.DoublyLinkedList.add(DoublyLinkedList.java:34)
    at datastructureproject.MergeSort.sort(MergeSort.java:31)
    at datastructureproject.DoublyLinkedList.main(DoublyLinkedList.java:82)
Java Result: 1
BUILD SUCCESSFUL (total time: 2 seconds)

PLEASE help me thanks alot.

+2  A: 

This is an unconventional "answer" -- I will be here for the next few hours, so I will try to guide you along the process of finding and fixing this bug.

Step 1. Failure capturing information in exceptions

The exception is thrown in getNodes by this check:

if (index < 0 || index > length) {
   throw new IndexOutOfBoundsException();

To ease debugging, you should always provide information for your exceptions (see: Effective Java 2nd Edition: Item 63: Include failure capture information in detail messages). The first step to help us identify and fix this bug is to do just that:

if (index < 0 || index > length) {
   throw new IndexOutOfBoundsException("Index=" + index + "; length=" + length);

Now, whenever the exception is thrown, we also get a detailed message of what the values of index and length was.


Intermission: Suspect #1

DoublyLinkedList listTwo = new DoublyLinkedList();
for (int x = (localDoublyLinkedList.size() / 2) + 1;
        x < localDoublyLinkedList.size(); x++) {
    listTwo.add(x, localDoublyLinkedList.getValue(x));
}

In all likelihood, this is the culprit. listTwo is empty when you try to add element at index x. Perhaps you want something like this:

DoublyLinkedList listTwo = new DoublyLinkedList();
for (int x = (localDoublyLinkedList.size() / 2) + 1, offset = x;
        x < localDoublyLinkedList.size(); x++) {
    listTwo.add(x - offset, localDoublyLinkedList.getValue(x));
}

This uses the offset calculation so that listTwo.add starts at index 0.


Intermission #2: Use more final local variables

I suggest having something like this:

final int L = localDoublyLinkedList.size();
final int M = L / 2;

Then using L and M in your algorithms to improve readability.

polygenelubricants
thanks for your attention!! I have run and debug it and the stack tarces were like those ones that I have written above.
Johanna
also I have done(offSet=x,...) but now it shows a lot of 0 in the concole!!!!
Johanna
@Johanna: I think your list splitting algorithm is `O(N^2)`. I suggest you actually structurally split the list in the middle, instead of creating two different lists. Even if you want to create two different lists, I suggest using a linear-time iteration instead of indexed `getValue()`, which in all likelihood is `O(N)` (for overall `O(N^2)` just to split).
polygenelubricants
@Johanna: I think your splitting is also off by one. In first loop, `x = 0; x < M; x++` and in second loop, `x = M + 1; x < L; x++`. Element at `M` is never `add`-ed.
polygenelubricants
So what hsould I do,really I hanged :(
Johanna
@Johanna: did you implement the failure capture feature I mentioned? What does it say? What was the `index` and what was the `length`?
polygenelubricants