How to do a Generic Merge Sort with the Java Interface Comparator?How to generate a random alpha-numeric string?How do I efficiently iterate over each entry in a Java Map?How do I call one constructor from another in Java?How do I read / convert an InputStream into a String in Java?How do I generate random integers within a specific range in Java?How do I determine whether an array contains a particular value in Java?How do I declare and initialize an array in Java?Comparing Java enum members: == or equals()?How to split a string in JavaHow do I convert a String to an int in Java?
Draw a checker pattern with a black X in the center
shutdown at specific date
Future enhancements for the finite element method
Can a Beholder use rays in melee range?
Do you play the upbeat when beginning to play a series of notes, and then after?
What caused the tendency for conservatives to not support climate change reform?
How can I find where certain bash function is defined?
Crossword gone overboard
What does the behaviour of water on the skin of an aircraft in flight tell us?
Could IPv6 make NAT / port numbers redundant?
What does "tea juice" mean in this context?
Smart people send dumb people to a new planet on a space craft that crashes into a body of water
Windows 10 Programs start without visual Interface
What are the problems in teaching guitar via Skype?
How did Vers know Agent Fury's name?
Infinitely many hats
The use of konnte
Restoring order in a deck of playing cards
Is it ok to put a subplot to a story that is never meant to contribute to the development of the main plot?
What are the benefits of cryosleep?
What's the connection between "kicking a pigeon" and "how a bill becomes a law"?
Preserving culinary oils
Which noble houses were destroyed during the Game of Thrones?
What are these (utility?) boxes at the side of the house?
How to do a Generic Merge Sort with the Java Interface Comparator?
How to generate a random alpha-numeric string?How do I efficiently iterate over each entry in a Java Map?How do I call one constructor from another in Java?How do I read / convert an InputStream into a String in Java?How do I generate random integers within a specific range in Java?How do I determine whether an array contains a particular value in Java?How do I declare and initialize an array in Java?Comparing Java enum members: == or equals()?How to split a string in JavaHow do I convert a String to an int in Java?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I'm trying to merge sort lists but get ArrayOutOfBoundsError and don't manage to fix it.
This is for generic Lists using the Comparator interface. For now I'm running test with Integer.
This is my merge sort class:
public class ListMS<T>
private List<T> wholeList;
private Comparator<T> comparator;
public ListMS(List<T> list, Comparator<T> C)
wholeList=new ArrayList<>();
wholeList.addAll(list);
comparator=C;
mergeSort(wholeList, comparator);
public static <T> void merge(List<T> L1, List<T> L2,List<T> L, Comparator<T> C)
int i=0;
int j=0;
while(i+j<L.size())
public static <T> void mergeSort(List<T> L, Comparator<T> C)
int size=L.size();
if(size<2)
return;
int half=size/2;
List<T> L1=L.subList(0,half);
List<T> L2=L.subList(half,size);
mergeSort(L1,C);
mergeSort(L1,C);
merge(L1,L2,L,C);
public List<T> getWholeList()
return wholeList;
What I'm testing it with:
public static void main(String[] args)
Comparator<Integer> C=new Comparator<Integer>()
@Override
public int compare(Integer o1, Integer o2)
return o1.compareTo(o2);
;
List<Integer> list1K=generateList(1000);
ListMS<Integer> list1KMerged=new ListMS<>(list1K, C);
printList(list1K);
printList(list1KMerged.getWholeList());
public static List<Integer> generateList(int size)
List<Integer> listNumber=new ArrayList<>();
for(int i=0;i<size;i++)
int min=0;
int max=size-1;
int num=(int)(Math.random() * ((max - min) + 1)) + min;
listNumber.add(num);
return listNumber;
public static void printList(List<Integer> L)
for(int i=0;i<L.size();i++)
System.out.print(L.get(i));
But I get multiple ArrayOutOfBounds:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index:
1, Size: 1 at
java.util.ArrayList$SubList.rangeCheck(ArrayList.java:1225) at
java.util.ArrayList$SubList.get(ArrayList.java:1042) at
ListMS.merge(ListMS.java:19) at ListMS.mergeSort(ListMS.java:40) at
ListMS.mergeSort(ListMS.java:37) at ListMS.mergeSort(ListMS.java:37)
at ListMS.mergeSort(ListMS.java:37) at
ListMS.mergeSort(ListMS.java:37) at ListMS.mergeSort(ListMS.java:37)
at ListMS.mergeSort(ListMS.java:37) at
ListMS.mergeSort(ListMS.java:37) at ListMS.mergeSort(ListMS.java:37)
at ListMS.(ListMS.java:11) at
TestListMS.main(TestListMS.java:16)
java algorithm arraylist mergesort
|
show 1 more comment
I'm trying to merge sort lists but get ArrayOutOfBoundsError and don't manage to fix it.
This is for generic Lists using the Comparator interface. For now I'm running test with Integer.
This is my merge sort class:
public class ListMS<T>
private List<T> wholeList;
private Comparator<T> comparator;
public ListMS(List<T> list, Comparator<T> C)
wholeList=new ArrayList<>();
wholeList.addAll(list);
comparator=C;
mergeSort(wholeList, comparator);
public static <T> void merge(List<T> L1, List<T> L2,List<T> L, Comparator<T> C)
int i=0;
int j=0;
while(i+j<L.size())
public static <T> void mergeSort(List<T> L, Comparator<T> C)
int size=L.size();
if(size<2)
return;
int half=size/2;
List<T> L1=L.subList(0,half);
List<T> L2=L.subList(half,size);
mergeSort(L1,C);
mergeSort(L1,C);
merge(L1,L2,L,C);
public List<T> getWholeList()
return wholeList;
What I'm testing it with:
public static void main(String[] args)
Comparator<Integer> C=new Comparator<Integer>()
@Override
public int compare(Integer o1, Integer o2)
return o1.compareTo(o2);
;
List<Integer> list1K=generateList(1000);
ListMS<Integer> list1KMerged=new ListMS<>(list1K, C);
printList(list1K);
printList(list1KMerged.getWholeList());
public static List<Integer> generateList(int size)
List<Integer> listNumber=new ArrayList<>();
for(int i=0;i<size;i++)
int min=0;
int max=size-1;
int num=(int)(Math.random() * ((max - min) + 1)) + min;
listNumber.add(num);
return listNumber;
public static void printList(List<Integer> L)
for(int i=0;i<L.size();i++)
System.out.print(L.get(i));
But I get multiple ArrayOutOfBounds:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index:
1, Size: 1 at
java.util.ArrayList$SubList.rangeCheck(ArrayList.java:1225) at
java.util.ArrayList$SubList.get(ArrayList.java:1042) at
ListMS.merge(ListMS.java:19) at ListMS.mergeSort(ListMS.java:40) at
ListMS.mergeSort(ListMS.java:37) at ListMS.mergeSort(ListMS.java:37)
at ListMS.mergeSort(ListMS.java:37) at
ListMS.mergeSort(ListMS.java:37) at ListMS.mergeSort(ListMS.java:37)
at ListMS.mergeSort(ListMS.java:37) at
ListMS.mergeSort(ListMS.java:37) at ListMS.mergeSort(ListMS.java:37)
at ListMS.(ListMS.java:11) at
TestListMS.main(TestListMS.java:16)
java algorithm arraylist mergesort
Which one is line 16?
– Aniket Sahrawat
Mar 24 at 8:58
@AniketSahrawat this line : ListMS<Integer> list1KMerged=new ListMS<>(list1K, C);
– Emma Vande Wouwer
Mar 24 at 9:00
Your merge method is wrong. You can't assume thati
andj
are valid indices ofL1
andL2
as long asi+j<L.size()
. You have to check whetheri
reachedL1.size()
orj
reachedL2.size()
.
– Eran
Mar 24 at 9:00
@Eran Switching my while to : while(i<L1.size() && j<L2.size()), you mean ? Or a bit further in my conditions ?
– Emma Vande Wouwer
Mar 24 at 9:05
@EmmaVandeWouwer yes, but in addition, after the loop you'll have to add any remaining elements of L1 or L2 to the end of L.
– Eran
Mar 24 at 9:10
|
show 1 more comment
I'm trying to merge sort lists but get ArrayOutOfBoundsError and don't manage to fix it.
This is for generic Lists using the Comparator interface. For now I'm running test with Integer.
This is my merge sort class:
public class ListMS<T>
private List<T> wholeList;
private Comparator<T> comparator;
public ListMS(List<T> list, Comparator<T> C)
wholeList=new ArrayList<>();
wholeList.addAll(list);
comparator=C;
mergeSort(wholeList, comparator);
public static <T> void merge(List<T> L1, List<T> L2,List<T> L, Comparator<T> C)
int i=0;
int j=0;
while(i+j<L.size())
public static <T> void mergeSort(List<T> L, Comparator<T> C)
int size=L.size();
if(size<2)
return;
int half=size/2;
List<T> L1=L.subList(0,half);
List<T> L2=L.subList(half,size);
mergeSort(L1,C);
mergeSort(L1,C);
merge(L1,L2,L,C);
public List<T> getWholeList()
return wholeList;
What I'm testing it with:
public static void main(String[] args)
Comparator<Integer> C=new Comparator<Integer>()
@Override
public int compare(Integer o1, Integer o2)
return o1.compareTo(o2);
;
List<Integer> list1K=generateList(1000);
ListMS<Integer> list1KMerged=new ListMS<>(list1K, C);
printList(list1K);
printList(list1KMerged.getWholeList());
public static List<Integer> generateList(int size)
List<Integer> listNumber=new ArrayList<>();
for(int i=0;i<size;i++)
int min=0;
int max=size-1;
int num=(int)(Math.random() * ((max - min) + 1)) + min;
listNumber.add(num);
return listNumber;
public static void printList(List<Integer> L)
for(int i=0;i<L.size();i++)
System.out.print(L.get(i));
But I get multiple ArrayOutOfBounds:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index:
1, Size: 1 at
java.util.ArrayList$SubList.rangeCheck(ArrayList.java:1225) at
java.util.ArrayList$SubList.get(ArrayList.java:1042) at
ListMS.merge(ListMS.java:19) at ListMS.mergeSort(ListMS.java:40) at
ListMS.mergeSort(ListMS.java:37) at ListMS.mergeSort(ListMS.java:37)
at ListMS.mergeSort(ListMS.java:37) at
ListMS.mergeSort(ListMS.java:37) at ListMS.mergeSort(ListMS.java:37)
at ListMS.mergeSort(ListMS.java:37) at
ListMS.mergeSort(ListMS.java:37) at ListMS.mergeSort(ListMS.java:37)
at ListMS.(ListMS.java:11) at
TestListMS.main(TestListMS.java:16)
java algorithm arraylist mergesort
I'm trying to merge sort lists but get ArrayOutOfBoundsError and don't manage to fix it.
This is for generic Lists using the Comparator interface. For now I'm running test with Integer.
This is my merge sort class:
public class ListMS<T>
private List<T> wholeList;
private Comparator<T> comparator;
public ListMS(List<T> list, Comparator<T> C)
wholeList=new ArrayList<>();
wholeList.addAll(list);
comparator=C;
mergeSort(wholeList, comparator);
public static <T> void merge(List<T> L1, List<T> L2,List<T> L, Comparator<T> C)
int i=0;
int j=0;
while(i+j<L.size())
public static <T> void mergeSort(List<T> L, Comparator<T> C)
int size=L.size();
if(size<2)
return;
int half=size/2;
List<T> L1=L.subList(0,half);
List<T> L2=L.subList(half,size);
mergeSort(L1,C);
mergeSort(L1,C);
merge(L1,L2,L,C);
public List<T> getWholeList()
return wholeList;
What I'm testing it with:
public static void main(String[] args)
Comparator<Integer> C=new Comparator<Integer>()
@Override
public int compare(Integer o1, Integer o2)
return o1.compareTo(o2);
;
List<Integer> list1K=generateList(1000);
ListMS<Integer> list1KMerged=new ListMS<>(list1K, C);
printList(list1K);
printList(list1KMerged.getWholeList());
public static List<Integer> generateList(int size)
List<Integer> listNumber=new ArrayList<>();
for(int i=0;i<size;i++)
int min=0;
int max=size-1;
int num=(int)(Math.random() * ((max - min) + 1)) + min;
listNumber.add(num);
return listNumber;
public static void printList(List<Integer> L)
for(int i=0;i<L.size();i++)
System.out.print(L.get(i));
But I get multiple ArrayOutOfBounds:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index:
1, Size: 1 at
java.util.ArrayList$SubList.rangeCheck(ArrayList.java:1225) at
java.util.ArrayList$SubList.get(ArrayList.java:1042) at
ListMS.merge(ListMS.java:19) at ListMS.mergeSort(ListMS.java:40) at
ListMS.mergeSort(ListMS.java:37) at ListMS.mergeSort(ListMS.java:37)
at ListMS.mergeSort(ListMS.java:37) at
ListMS.mergeSort(ListMS.java:37) at ListMS.mergeSort(ListMS.java:37)
at ListMS.mergeSort(ListMS.java:37) at
ListMS.mergeSort(ListMS.java:37) at ListMS.mergeSort(ListMS.java:37)
at ListMS.(ListMS.java:11) at
TestListMS.main(TestListMS.java:16)
java algorithm arraylist mergesort
java algorithm arraylist mergesort
asked Mar 24 at 8:55
Emma Vande WouwerEmma Vande Wouwer
84
84
Which one is line 16?
– Aniket Sahrawat
Mar 24 at 8:58
@AniketSahrawat this line : ListMS<Integer> list1KMerged=new ListMS<>(list1K, C);
– Emma Vande Wouwer
Mar 24 at 9:00
Your merge method is wrong. You can't assume thati
andj
are valid indices ofL1
andL2
as long asi+j<L.size()
. You have to check whetheri
reachedL1.size()
orj
reachedL2.size()
.
– Eran
Mar 24 at 9:00
@Eran Switching my while to : while(i<L1.size() && j<L2.size()), you mean ? Or a bit further in my conditions ?
– Emma Vande Wouwer
Mar 24 at 9:05
@EmmaVandeWouwer yes, but in addition, after the loop you'll have to add any remaining elements of L1 or L2 to the end of L.
– Eran
Mar 24 at 9:10
|
show 1 more comment
Which one is line 16?
– Aniket Sahrawat
Mar 24 at 8:58
@AniketSahrawat this line : ListMS<Integer> list1KMerged=new ListMS<>(list1K, C);
– Emma Vande Wouwer
Mar 24 at 9:00
Your merge method is wrong. You can't assume thati
andj
are valid indices ofL1
andL2
as long asi+j<L.size()
. You have to check whetheri
reachedL1.size()
orj
reachedL2.size()
.
– Eran
Mar 24 at 9:00
@Eran Switching my while to : while(i<L1.size() && j<L2.size()), you mean ? Or a bit further in my conditions ?
– Emma Vande Wouwer
Mar 24 at 9:05
@EmmaVandeWouwer yes, but in addition, after the loop you'll have to add any remaining elements of L1 or L2 to the end of L.
– Eran
Mar 24 at 9:10
Which one is line 16?
– Aniket Sahrawat
Mar 24 at 8:58
Which one is line 16?
– Aniket Sahrawat
Mar 24 at 8:58
@AniketSahrawat this line : ListMS<Integer> list1KMerged=new ListMS<>(list1K, C);
– Emma Vande Wouwer
Mar 24 at 9:00
@AniketSahrawat this line : ListMS<Integer> list1KMerged=new ListMS<>(list1K, C);
– Emma Vande Wouwer
Mar 24 at 9:00
Your merge method is wrong. You can't assume that
i
and j
are valid indices of L1
and L2
as long as i+j<L.size()
. You have to check whether i
reached L1.size()
or j
reached L2.size()
.– Eran
Mar 24 at 9:00
Your merge method is wrong. You can't assume that
i
and j
are valid indices of L1
and L2
as long as i+j<L.size()
. You have to check whether i
reached L1.size()
or j
reached L2.size()
.– Eran
Mar 24 at 9:00
@Eran Switching my while to : while(i<L1.size() && j<L2.size()), you mean ? Or a bit further in my conditions ?
– Emma Vande Wouwer
Mar 24 at 9:05
@Eran Switching my while to : while(i<L1.size() && j<L2.size()), you mean ? Or a bit further in my conditions ?
– Emma Vande Wouwer
Mar 24 at 9:05
@EmmaVandeWouwer yes, but in addition, after the loop you'll have to add any remaining elements of L1 or L2 to the end of L.
– Eran
Mar 24 at 9:10
@EmmaVandeWouwer yes, but in addition, after the loop you'll have to add any remaining elements of L1 or L2 to the end of L.
– Eran
Mar 24 at 9:10
|
show 1 more comment
1 Answer
1
active
oldest
votes
Basically, there is an error in your loop counters in merge() methid at this line:
if(j == L2.size() || (i < L.size() && C.compare(L1.get(i), L2.get(j)) < 0))
Modify the merge function as so, it will work:
public static <T> void merge(List<T> L1, List<T> L2,List<T> L, Comparator<T> C)
int i=0;
int j=0;
int k=0;
while(i < L1.size() && j < L2.size())
if(C.compare(L1.get(i), L2.get(j)) < 0)
L.set(k++, L1.get(i++));
else
L.set(k++, L2.get(j++));
while(i < L1.size())
L.set(k++, L1.get(i++));
while(j < L2.size())
L.set(k++, L2.get(j++));
UPDATE:
There are multiple errors in mergeSort function as well. Change it as so:
public static <T> void mergeSort(List<T> L, Comparator<T> C)
int size=L.size();
if(size<2)
return;
int half=size/2;
List<T> L1=new ArrayList<T>(L.subList(0,half));
List<T> L2=new ArrayList<T>(L.subList(half,size));
mergeSort(L1,C);
mergeSort(L2,C);
merge(L1,L2,L,C);
printList(L);
L1 and L2 were not new array-list in old code. They were just two pointers pointing to same memory locations as in the List L. So modifying L in merge function also modified L1 and L2. In order to solve this, you need to create two new subarrays with separate memory allocations.
Also you were calling mergeSort(L1,C);
twice instead of calling it on L1 and L2 each.
Thank you for your help. Unfortunately, the output I get is wrong. The first half is the same repeating number and the second half is in the same order as the original list
– Emma Vande Wouwer
Mar 24 at 9:28
Update the answer. There were errors in your mergesort function as well.
– raviiii1
Mar 24 at 9:35
Perfect ! Thank you so much
– Emma Vande Wouwer
Mar 24 at 9:38
While in-place merge-sort is hard, there is overhead, but no need to reallocate with every recursive call. In a non-concurrent implementation, you can get by using one buffer half the size ofL
. Using an array for "the other buffer" would open an interesting can of worms. For speed, instantiating anArrayList
to replaceL
but for the destination of the final merge whenL
doesn't implementRandomAccess
looks an option to evaluate. (Part of the performance problems to be expected could be sidestepped usingIterator
s.)
– greybeard
Mar 24 at 10:16
(I may have been thinking all purpose where the question reads generic.)
– greybeard
Mar 24 at 11:01
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55322118%2fhow-to-do-a-generic-merge-sort-with-the-java-interface-comparator%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Basically, there is an error in your loop counters in merge() methid at this line:
if(j == L2.size() || (i < L.size() && C.compare(L1.get(i), L2.get(j)) < 0))
Modify the merge function as so, it will work:
public static <T> void merge(List<T> L1, List<T> L2,List<T> L, Comparator<T> C)
int i=0;
int j=0;
int k=0;
while(i < L1.size() && j < L2.size())
if(C.compare(L1.get(i), L2.get(j)) < 0)
L.set(k++, L1.get(i++));
else
L.set(k++, L2.get(j++));
while(i < L1.size())
L.set(k++, L1.get(i++));
while(j < L2.size())
L.set(k++, L2.get(j++));
UPDATE:
There are multiple errors in mergeSort function as well. Change it as so:
public static <T> void mergeSort(List<T> L, Comparator<T> C)
int size=L.size();
if(size<2)
return;
int half=size/2;
List<T> L1=new ArrayList<T>(L.subList(0,half));
List<T> L2=new ArrayList<T>(L.subList(half,size));
mergeSort(L1,C);
mergeSort(L2,C);
merge(L1,L2,L,C);
printList(L);
L1 and L2 were not new array-list in old code. They were just two pointers pointing to same memory locations as in the List L. So modifying L in merge function also modified L1 and L2. In order to solve this, you need to create two new subarrays with separate memory allocations.
Also you were calling mergeSort(L1,C);
twice instead of calling it on L1 and L2 each.
Thank you for your help. Unfortunately, the output I get is wrong. The first half is the same repeating number and the second half is in the same order as the original list
– Emma Vande Wouwer
Mar 24 at 9:28
Update the answer. There were errors in your mergesort function as well.
– raviiii1
Mar 24 at 9:35
Perfect ! Thank you so much
– Emma Vande Wouwer
Mar 24 at 9:38
While in-place merge-sort is hard, there is overhead, but no need to reallocate with every recursive call. In a non-concurrent implementation, you can get by using one buffer half the size ofL
. Using an array for "the other buffer" would open an interesting can of worms. For speed, instantiating anArrayList
to replaceL
but for the destination of the final merge whenL
doesn't implementRandomAccess
looks an option to evaluate. (Part of the performance problems to be expected could be sidestepped usingIterator
s.)
– greybeard
Mar 24 at 10:16
(I may have been thinking all purpose where the question reads generic.)
– greybeard
Mar 24 at 11:01
add a comment |
Basically, there is an error in your loop counters in merge() methid at this line:
if(j == L2.size() || (i < L.size() && C.compare(L1.get(i), L2.get(j)) < 0))
Modify the merge function as so, it will work:
public static <T> void merge(List<T> L1, List<T> L2,List<T> L, Comparator<T> C)
int i=0;
int j=0;
int k=0;
while(i < L1.size() && j < L2.size())
if(C.compare(L1.get(i), L2.get(j)) < 0)
L.set(k++, L1.get(i++));
else
L.set(k++, L2.get(j++));
while(i < L1.size())
L.set(k++, L1.get(i++));
while(j < L2.size())
L.set(k++, L2.get(j++));
UPDATE:
There are multiple errors in mergeSort function as well. Change it as so:
public static <T> void mergeSort(List<T> L, Comparator<T> C)
int size=L.size();
if(size<2)
return;
int half=size/2;
List<T> L1=new ArrayList<T>(L.subList(0,half));
List<T> L2=new ArrayList<T>(L.subList(half,size));
mergeSort(L1,C);
mergeSort(L2,C);
merge(L1,L2,L,C);
printList(L);
L1 and L2 were not new array-list in old code. They were just two pointers pointing to same memory locations as in the List L. So modifying L in merge function also modified L1 and L2. In order to solve this, you need to create two new subarrays with separate memory allocations.
Also you were calling mergeSort(L1,C);
twice instead of calling it on L1 and L2 each.
Thank you for your help. Unfortunately, the output I get is wrong. The first half is the same repeating number and the second half is in the same order as the original list
– Emma Vande Wouwer
Mar 24 at 9:28
Update the answer. There were errors in your mergesort function as well.
– raviiii1
Mar 24 at 9:35
Perfect ! Thank you so much
– Emma Vande Wouwer
Mar 24 at 9:38
While in-place merge-sort is hard, there is overhead, but no need to reallocate with every recursive call. In a non-concurrent implementation, you can get by using one buffer half the size ofL
. Using an array for "the other buffer" would open an interesting can of worms. For speed, instantiating anArrayList
to replaceL
but for the destination of the final merge whenL
doesn't implementRandomAccess
looks an option to evaluate. (Part of the performance problems to be expected could be sidestepped usingIterator
s.)
– greybeard
Mar 24 at 10:16
(I may have been thinking all purpose where the question reads generic.)
– greybeard
Mar 24 at 11:01
add a comment |
Basically, there is an error in your loop counters in merge() methid at this line:
if(j == L2.size() || (i < L.size() && C.compare(L1.get(i), L2.get(j)) < 0))
Modify the merge function as so, it will work:
public static <T> void merge(List<T> L1, List<T> L2,List<T> L, Comparator<T> C)
int i=0;
int j=0;
int k=0;
while(i < L1.size() && j < L2.size())
if(C.compare(L1.get(i), L2.get(j)) < 0)
L.set(k++, L1.get(i++));
else
L.set(k++, L2.get(j++));
while(i < L1.size())
L.set(k++, L1.get(i++));
while(j < L2.size())
L.set(k++, L2.get(j++));
UPDATE:
There are multiple errors in mergeSort function as well. Change it as so:
public static <T> void mergeSort(List<T> L, Comparator<T> C)
int size=L.size();
if(size<2)
return;
int half=size/2;
List<T> L1=new ArrayList<T>(L.subList(0,half));
List<T> L2=new ArrayList<T>(L.subList(half,size));
mergeSort(L1,C);
mergeSort(L2,C);
merge(L1,L2,L,C);
printList(L);
L1 and L2 were not new array-list in old code. They were just two pointers pointing to same memory locations as in the List L. So modifying L in merge function also modified L1 and L2. In order to solve this, you need to create two new subarrays with separate memory allocations.
Also you were calling mergeSort(L1,C);
twice instead of calling it on L1 and L2 each.
Basically, there is an error in your loop counters in merge() methid at this line:
if(j == L2.size() || (i < L.size() && C.compare(L1.get(i), L2.get(j)) < 0))
Modify the merge function as so, it will work:
public static <T> void merge(List<T> L1, List<T> L2,List<T> L, Comparator<T> C)
int i=0;
int j=0;
int k=0;
while(i < L1.size() && j < L2.size())
if(C.compare(L1.get(i), L2.get(j)) < 0)
L.set(k++, L1.get(i++));
else
L.set(k++, L2.get(j++));
while(i < L1.size())
L.set(k++, L1.get(i++));
while(j < L2.size())
L.set(k++, L2.get(j++));
UPDATE:
There are multiple errors in mergeSort function as well. Change it as so:
public static <T> void mergeSort(List<T> L, Comparator<T> C)
int size=L.size();
if(size<2)
return;
int half=size/2;
List<T> L1=new ArrayList<T>(L.subList(0,half));
List<T> L2=new ArrayList<T>(L.subList(half,size));
mergeSort(L1,C);
mergeSort(L2,C);
merge(L1,L2,L,C);
printList(L);
L1 and L2 were not new array-list in old code. They were just two pointers pointing to same memory locations as in the List L. So modifying L in merge function also modified L1 and L2. In order to solve this, you need to create two new subarrays with separate memory allocations.
Also you were calling mergeSort(L1,C);
twice instead of calling it on L1 and L2 each.
edited Mar 24 at 9:45
YCF_L
34.8k104687
34.8k104687
answered Mar 24 at 9:16
raviiii1raviiii1
576416
576416
Thank you for your help. Unfortunately, the output I get is wrong. The first half is the same repeating number and the second half is in the same order as the original list
– Emma Vande Wouwer
Mar 24 at 9:28
Update the answer. There were errors in your mergesort function as well.
– raviiii1
Mar 24 at 9:35
Perfect ! Thank you so much
– Emma Vande Wouwer
Mar 24 at 9:38
While in-place merge-sort is hard, there is overhead, but no need to reallocate with every recursive call. In a non-concurrent implementation, you can get by using one buffer half the size ofL
. Using an array for "the other buffer" would open an interesting can of worms. For speed, instantiating anArrayList
to replaceL
but for the destination of the final merge whenL
doesn't implementRandomAccess
looks an option to evaluate. (Part of the performance problems to be expected could be sidestepped usingIterator
s.)
– greybeard
Mar 24 at 10:16
(I may have been thinking all purpose where the question reads generic.)
– greybeard
Mar 24 at 11:01
add a comment |
Thank you for your help. Unfortunately, the output I get is wrong. The first half is the same repeating number and the second half is in the same order as the original list
– Emma Vande Wouwer
Mar 24 at 9:28
Update the answer. There were errors in your mergesort function as well.
– raviiii1
Mar 24 at 9:35
Perfect ! Thank you so much
– Emma Vande Wouwer
Mar 24 at 9:38
While in-place merge-sort is hard, there is overhead, but no need to reallocate with every recursive call. In a non-concurrent implementation, you can get by using one buffer half the size ofL
. Using an array for "the other buffer" would open an interesting can of worms. For speed, instantiating anArrayList
to replaceL
but for the destination of the final merge whenL
doesn't implementRandomAccess
looks an option to evaluate. (Part of the performance problems to be expected could be sidestepped usingIterator
s.)
– greybeard
Mar 24 at 10:16
(I may have been thinking all purpose where the question reads generic.)
– greybeard
Mar 24 at 11:01
Thank you for your help. Unfortunately, the output I get is wrong. The first half is the same repeating number and the second half is in the same order as the original list
– Emma Vande Wouwer
Mar 24 at 9:28
Thank you for your help. Unfortunately, the output I get is wrong. The first half is the same repeating number and the second half is in the same order as the original list
– Emma Vande Wouwer
Mar 24 at 9:28
Update the answer. There were errors in your mergesort function as well.
– raviiii1
Mar 24 at 9:35
Update the answer. There were errors in your mergesort function as well.
– raviiii1
Mar 24 at 9:35
Perfect ! Thank you so much
– Emma Vande Wouwer
Mar 24 at 9:38
Perfect ! Thank you so much
– Emma Vande Wouwer
Mar 24 at 9:38
While in-place merge-sort is hard, there is overhead, but no need to reallocate with every recursive call. In a non-concurrent implementation, you can get by using one buffer half the size of
L
. Using an array for "the other buffer" would open an interesting can of worms. For speed, instantiating an ArrayList
to replace L
but for the destination of the final merge when L
doesn't implement RandomAccess
looks an option to evaluate. (Part of the performance problems to be expected could be sidestepped using Iterator
s.)– greybeard
Mar 24 at 10:16
While in-place merge-sort is hard, there is overhead, but no need to reallocate with every recursive call. In a non-concurrent implementation, you can get by using one buffer half the size of
L
. Using an array for "the other buffer" would open an interesting can of worms. For speed, instantiating an ArrayList
to replace L
but for the destination of the final merge when L
doesn't implement RandomAccess
looks an option to evaluate. (Part of the performance problems to be expected could be sidestepped using Iterator
s.)– greybeard
Mar 24 at 10:16
(I may have been thinking all purpose where the question reads generic.)
– greybeard
Mar 24 at 11:01
(I may have been thinking all purpose where the question reads generic.)
– greybeard
Mar 24 at 11:01
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55322118%2fhow-to-do-a-generic-merge-sort-with-the-java-interface-comparator%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Which one is line 16?
– Aniket Sahrawat
Mar 24 at 8:58
@AniketSahrawat this line : ListMS<Integer> list1KMerged=new ListMS<>(list1K, C);
– Emma Vande Wouwer
Mar 24 at 9:00
Your merge method is wrong. You can't assume that
i
andj
are valid indices ofL1
andL2
as long asi+j<L.size()
. You have to check whetheri
reachedL1.size()
orj
reachedL2.size()
.– Eran
Mar 24 at 9:00
@Eran Switching my while to : while(i<L1.size() && j<L2.size()), you mean ? Or a bit further in my conditions ?
– Emma Vande Wouwer
Mar 24 at 9:05
@EmmaVandeWouwer yes, but in addition, after the loop you'll have to add any remaining elements of L1 or L2 to the end of L.
– Eran
Mar 24 at 9:10