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;








0















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)











share|improve this question






















  • 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 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











  • @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

















0















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)











share|improve this question






















  • 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 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











  • @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













0












0








0








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)











share|improve this question














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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










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 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











  • @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











  • @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











  • @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












1 Answer
1






active

oldest

votes


















1














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.






share|improve this answer

























  • 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 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 Iterators.)

    – greybeard
    Mar 24 at 10:16












  • (I may have been thinking all purpose where the question reads generic.)

    – greybeard
    Mar 24 at 11:01











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
);



);













draft saved

draft discarded


















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









1














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.






share|improve this answer

























  • 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 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 Iterators.)

    – greybeard
    Mar 24 at 10:16












  • (I may have been thinking all purpose where the question reads generic.)

    – greybeard
    Mar 24 at 11:01















1














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.






share|improve this answer

























  • 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 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 Iterators.)

    – greybeard
    Mar 24 at 10:16












  • (I may have been thinking all purpose where the question reads generic.)

    – greybeard
    Mar 24 at 11:01













1












1








1







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.






share|improve this answer















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.







share|improve this answer














share|improve this answer



share|improve this answer








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 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 Iterators.)

    – 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












  • 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 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 Iterators.)

    – 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 Iterators.)

– 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 Iterators.)

– 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



















draft saved

draft discarded
















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript