Generic MergeSort Java Implementation Stack Overflow error











up vote
0
down vote

favorite












I'm trying to write a generic Merge sort method in Java.



This is my source code:



import java.util.ArrayList;
import java.util.List;

/**
* An implementation of MergeSort
*
* @param <T> the type of data held by the array.
*/
public class MergeSort<T extends Comparable<? super T>> implements ArraySort<T>
{
/**
* Sort the array using a MergeSort.
*
* (recursively breaks down the array into sub arrays until arrays of size 1 are reached.)
* (then works backwards merging these arrays back into each other until a sorted array state is reached containing
* all the elements of the initial unsorted array, but now sorted).
*
* @param array the array to be sorted.
* @return array (sorted)
*/
@Override
public T sort(T array)
{
//If the array being sorted is less than 2 elements, it is already sorted and cannot be split into two separate
// arrays, so return the initial array to prevent an exception.
if(array.length < 2)
{
return array;
}

//Create two sub arrays from the initial array passed in.
T temp1 = copy(array, 0, (array.length/2) - 1);
T temp2 = copy(array, (array.length/2), array.length - 1);

//Sort these two arrays.
sort(temp1);
sort(temp2);

//Merge the two subarrays back into the initial array.
merge(array, temp1, temp2);

//return the now sorted array.
return array;
}

/**
* Create and return a new array, comprised of a sublist of a passed in array.
*
* @param list the array to create the subarray from.
* @param from the lower bound within list to copy.
* @param to the upper bound within list to copy.
* @return a new list comprised of the elements from 'from' to 'to' in 'list'
*/
private <T> T copy(T list, int from, int to)
{
List<T> copyL = new ArrayList<>();
for(int i = 0; i < to - from + 1; i++)
{
copyL.add(list[from + i]);
}
return copyL.toArray(list);
}

/**
* Merge two sorted arrays into one larger array, keeping the sorted.
*
* @param target the array to merge source1 and source2 into.
* @param source1 a sorted array
* @param source2 a second sorted array.
*/
private void merge(T target, T source1, T source2)
{
//Variables to keep track of the smallest unused element in each source array.
int source1Index = 0;
int source2Index = 0;

//targetIndex keeps track of the next index to place the next smallest element into.
for(int targetIndex = 0; targetIndex < target.length; targetIndex++)
{
//Choose the smallest element from the two source arrays to place into the target(sorted) array
if(source1[source1Index].compareTo(source2[source2Index]) < 0)
{
target[targetIndex] = source1[source1Index];
source1Index++;
}
else
{
target[targetIndex] = source2[source2Index++];
source2Index++;
}
}
}
}


I have no idea why but I'm getting StackOverflow errors when I call line 38 and 42.



38 = T temp1 = copy(...) in the sort() method
42 = sort(temp1) in the sort() method.


This leads me to believe the error is somewhere in the copy function, but I don't know how to fix the problem or come to a solution.



Can somebody help me fix this implementation of a generic merge sort please?



StackTrace for sorting an array of 12 elements.



https://docs.google.com/document/d/1Ig5p7TZF_eX0Q_rroORnZUWnXtep7x-7cmDiSAZWlj8/edit?usp=sharing










share|improve this question
























  • Please copy the real stacktrace.
    – StephaneM
    Nov 13 at 14:07















up vote
0
down vote

favorite












I'm trying to write a generic Merge sort method in Java.



This is my source code:



import java.util.ArrayList;
import java.util.List;

/**
* An implementation of MergeSort
*
* @param <T> the type of data held by the array.
*/
public class MergeSort<T extends Comparable<? super T>> implements ArraySort<T>
{
/**
* Sort the array using a MergeSort.
*
* (recursively breaks down the array into sub arrays until arrays of size 1 are reached.)
* (then works backwards merging these arrays back into each other until a sorted array state is reached containing
* all the elements of the initial unsorted array, but now sorted).
*
* @param array the array to be sorted.
* @return array (sorted)
*/
@Override
public T sort(T array)
{
//If the array being sorted is less than 2 elements, it is already sorted and cannot be split into two separate
// arrays, so return the initial array to prevent an exception.
if(array.length < 2)
{
return array;
}

//Create two sub arrays from the initial array passed in.
T temp1 = copy(array, 0, (array.length/2) - 1);
T temp2 = copy(array, (array.length/2), array.length - 1);

//Sort these two arrays.
sort(temp1);
sort(temp2);

//Merge the two subarrays back into the initial array.
merge(array, temp1, temp2);

//return the now sorted array.
return array;
}

/**
* Create and return a new array, comprised of a sublist of a passed in array.
*
* @param list the array to create the subarray from.
* @param from the lower bound within list to copy.
* @param to the upper bound within list to copy.
* @return a new list comprised of the elements from 'from' to 'to' in 'list'
*/
private <T> T copy(T list, int from, int to)
{
List<T> copyL = new ArrayList<>();
for(int i = 0; i < to - from + 1; i++)
{
copyL.add(list[from + i]);
}
return copyL.toArray(list);
}

/**
* Merge two sorted arrays into one larger array, keeping the sorted.
*
* @param target the array to merge source1 and source2 into.
* @param source1 a sorted array
* @param source2 a second sorted array.
*/
private void merge(T target, T source1, T source2)
{
//Variables to keep track of the smallest unused element in each source array.
int source1Index = 0;
int source2Index = 0;

//targetIndex keeps track of the next index to place the next smallest element into.
for(int targetIndex = 0; targetIndex < target.length; targetIndex++)
{
//Choose the smallest element from the two source arrays to place into the target(sorted) array
if(source1[source1Index].compareTo(source2[source2Index]) < 0)
{
target[targetIndex] = source1[source1Index];
source1Index++;
}
else
{
target[targetIndex] = source2[source2Index++];
source2Index++;
}
}
}
}


I have no idea why but I'm getting StackOverflow errors when I call line 38 and 42.



38 = T temp1 = copy(...) in the sort() method
42 = sort(temp1) in the sort() method.


This leads me to believe the error is somewhere in the copy function, but I don't know how to fix the problem or come to a solution.



Can somebody help me fix this implementation of a generic merge sort please?



StackTrace for sorting an array of 12 elements.



https://docs.google.com/document/d/1Ig5p7TZF_eX0Q_rroORnZUWnXtep7x-7cmDiSAZWlj8/edit?usp=sharing










share|improve this question
























  • Please copy the real stacktrace.
    – StephaneM
    Nov 13 at 14:07













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I'm trying to write a generic Merge sort method in Java.



This is my source code:



import java.util.ArrayList;
import java.util.List;

/**
* An implementation of MergeSort
*
* @param <T> the type of data held by the array.
*/
public class MergeSort<T extends Comparable<? super T>> implements ArraySort<T>
{
/**
* Sort the array using a MergeSort.
*
* (recursively breaks down the array into sub arrays until arrays of size 1 are reached.)
* (then works backwards merging these arrays back into each other until a sorted array state is reached containing
* all the elements of the initial unsorted array, but now sorted).
*
* @param array the array to be sorted.
* @return array (sorted)
*/
@Override
public T sort(T array)
{
//If the array being sorted is less than 2 elements, it is already sorted and cannot be split into two separate
// arrays, so return the initial array to prevent an exception.
if(array.length < 2)
{
return array;
}

//Create two sub arrays from the initial array passed in.
T temp1 = copy(array, 0, (array.length/2) - 1);
T temp2 = copy(array, (array.length/2), array.length - 1);

//Sort these two arrays.
sort(temp1);
sort(temp2);

//Merge the two subarrays back into the initial array.
merge(array, temp1, temp2);

//return the now sorted array.
return array;
}

/**
* Create and return a new array, comprised of a sublist of a passed in array.
*
* @param list the array to create the subarray from.
* @param from the lower bound within list to copy.
* @param to the upper bound within list to copy.
* @return a new list comprised of the elements from 'from' to 'to' in 'list'
*/
private <T> T copy(T list, int from, int to)
{
List<T> copyL = new ArrayList<>();
for(int i = 0; i < to - from + 1; i++)
{
copyL.add(list[from + i]);
}
return copyL.toArray(list);
}

/**
* Merge two sorted arrays into one larger array, keeping the sorted.
*
* @param target the array to merge source1 and source2 into.
* @param source1 a sorted array
* @param source2 a second sorted array.
*/
private void merge(T target, T source1, T source2)
{
//Variables to keep track of the smallest unused element in each source array.
int source1Index = 0;
int source2Index = 0;

//targetIndex keeps track of the next index to place the next smallest element into.
for(int targetIndex = 0; targetIndex < target.length; targetIndex++)
{
//Choose the smallest element from the two source arrays to place into the target(sorted) array
if(source1[source1Index].compareTo(source2[source2Index]) < 0)
{
target[targetIndex] = source1[source1Index];
source1Index++;
}
else
{
target[targetIndex] = source2[source2Index++];
source2Index++;
}
}
}
}


I have no idea why but I'm getting StackOverflow errors when I call line 38 and 42.



38 = T temp1 = copy(...) in the sort() method
42 = sort(temp1) in the sort() method.


This leads me to believe the error is somewhere in the copy function, but I don't know how to fix the problem or come to a solution.



Can somebody help me fix this implementation of a generic merge sort please?



StackTrace for sorting an array of 12 elements.



https://docs.google.com/document/d/1Ig5p7TZF_eX0Q_rroORnZUWnXtep7x-7cmDiSAZWlj8/edit?usp=sharing










share|improve this question















I'm trying to write a generic Merge sort method in Java.



This is my source code:



import java.util.ArrayList;
import java.util.List;

/**
* An implementation of MergeSort
*
* @param <T> the type of data held by the array.
*/
public class MergeSort<T extends Comparable<? super T>> implements ArraySort<T>
{
/**
* Sort the array using a MergeSort.
*
* (recursively breaks down the array into sub arrays until arrays of size 1 are reached.)
* (then works backwards merging these arrays back into each other until a sorted array state is reached containing
* all the elements of the initial unsorted array, but now sorted).
*
* @param array the array to be sorted.
* @return array (sorted)
*/
@Override
public T sort(T array)
{
//If the array being sorted is less than 2 elements, it is already sorted and cannot be split into two separate
// arrays, so return the initial array to prevent an exception.
if(array.length < 2)
{
return array;
}

//Create two sub arrays from the initial array passed in.
T temp1 = copy(array, 0, (array.length/2) - 1);
T temp2 = copy(array, (array.length/2), array.length - 1);

//Sort these two arrays.
sort(temp1);
sort(temp2);

//Merge the two subarrays back into the initial array.
merge(array, temp1, temp2);

//return the now sorted array.
return array;
}

/**
* Create and return a new array, comprised of a sublist of a passed in array.
*
* @param list the array to create the subarray from.
* @param from the lower bound within list to copy.
* @param to the upper bound within list to copy.
* @return a new list comprised of the elements from 'from' to 'to' in 'list'
*/
private <T> T copy(T list, int from, int to)
{
List<T> copyL = new ArrayList<>();
for(int i = 0; i < to - from + 1; i++)
{
copyL.add(list[from + i]);
}
return copyL.toArray(list);
}

/**
* Merge two sorted arrays into one larger array, keeping the sorted.
*
* @param target the array to merge source1 and source2 into.
* @param source1 a sorted array
* @param source2 a second sorted array.
*/
private void merge(T target, T source1, T source2)
{
//Variables to keep track of the smallest unused element in each source array.
int source1Index = 0;
int source2Index = 0;

//targetIndex keeps track of the next index to place the next smallest element into.
for(int targetIndex = 0; targetIndex < target.length; targetIndex++)
{
//Choose the smallest element from the two source arrays to place into the target(sorted) array
if(source1[source1Index].compareTo(source2[source2Index]) < 0)
{
target[targetIndex] = source1[source1Index];
source1Index++;
}
else
{
target[targetIndex] = source2[source2Index++];
source2Index++;
}
}
}
}


I have no idea why but I'm getting StackOverflow errors when I call line 38 and 42.



38 = T temp1 = copy(...) in the sort() method
42 = sort(temp1) in the sort() method.


This leads me to believe the error is somewhere in the copy function, but I don't know how to fix the problem or come to a solution.



Can somebody help me fix this implementation of a generic merge sort please?



StackTrace for sorting an array of 12 elements.



https://docs.google.com/document/d/1Ig5p7TZF_eX0Q_rroORnZUWnXtep7x-7cmDiSAZWlj8/edit?usp=sharing







java sorting generics mergesort






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 at 14:12

























asked Nov 13 at 14:04









Natalo77

11




11












  • Please copy the real stacktrace.
    – StephaneM
    Nov 13 at 14:07


















  • Please copy the real stacktrace.
    – StephaneM
    Nov 13 at 14:07
















Please copy the real stacktrace.
– StephaneM
Nov 13 at 14:07




Please copy the real stacktrace.
– StephaneM
Nov 13 at 14:07












2 Answers
2






active

oldest

votes

















up vote
1
down vote













Your array copying is wrong.



Use:



    private <T> T copy(T list, int from, int to) {
return Arrays.copyOfRange(list, from, to);
}


There are more bugs in your code (merge doesn't handle different length arrays) but this should fix your problem.



See List.toArray(T)




... If the list fits in the specified array, it is returned therein.




i.e. you are copying into the original array, not creating a new one, so your arrays never actually decrease in size.






share|improve this answer





















  • Also sort(temp1); sort(temp2); should be temp1=sort(temp1); temp2=sort(temp2);
    – Eugen Covaci
    Nov 13 at 14:37










  • And (array.length/2) - 1 equals -1 for array.length =1
    – Eugen Covaci
    Nov 13 at 14:40


















up vote
0
down vote













Your conditional are not good enough, you get infinite sort call on your arrays.



At least you should include array of size equals to 2 :



if(array.length <= 2)


In addition, your copy method must be improved.



Anyway, copy/paste your full stack trace please.






share|improve this answer























  • can you access the google docs in the question?
    – Natalo77
    Nov 13 at 14:27










  • Yes I do, and it confirms calling endlessly your sort method.
    – Bsquare
    Nov 13 at 14:32











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',
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%2f53282765%2fgeneric-mergesort-java-implementation-stack-overflow-error%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
1
down vote













Your array copying is wrong.



Use:



    private <T> T copy(T list, int from, int to) {
return Arrays.copyOfRange(list, from, to);
}


There are more bugs in your code (merge doesn't handle different length arrays) but this should fix your problem.



See List.toArray(T)




... If the list fits in the specified array, it is returned therein.




i.e. you are copying into the original array, not creating a new one, so your arrays never actually decrease in size.






share|improve this answer





















  • Also sort(temp1); sort(temp2); should be temp1=sort(temp1); temp2=sort(temp2);
    – Eugen Covaci
    Nov 13 at 14:37










  • And (array.length/2) - 1 equals -1 for array.length =1
    – Eugen Covaci
    Nov 13 at 14:40















up vote
1
down vote













Your array copying is wrong.



Use:



    private <T> T copy(T list, int from, int to) {
return Arrays.copyOfRange(list, from, to);
}


There are more bugs in your code (merge doesn't handle different length arrays) but this should fix your problem.



See List.toArray(T)




... If the list fits in the specified array, it is returned therein.




i.e. you are copying into the original array, not creating a new one, so your arrays never actually decrease in size.






share|improve this answer





















  • Also sort(temp1); sort(temp2); should be temp1=sort(temp1); temp2=sort(temp2);
    – Eugen Covaci
    Nov 13 at 14:37










  • And (array.length/2) - 1 equals -1 for array.length =1
    – Eugen Covaci
    Nov 13 at 14:40













up vote
1
down vote










up vote
1
down vote









Your array copying is wrong.



Use:



    private <T> T copy(T list, int from, int to) {
return Arrays.copyOfRange(list, from, to);
}


There are more bugs in your code (merge doesn't handle different length arrays) but this should fix your problem.



See List.toArray(T)




... If the list fits in the specified array, it is returned therein.




i.e. you are copying into the original array, not creating a new one, so your arrays never actually decrease in size.






share|improve this answer












Your array copying is wrong.



Use:



    private <T> T copy(T list, int from, int to) {
return Arrays.copyOfRange(list, from, to);
}


There are more bugs in your code (merge doesn't handle different length arrays) but this should fix your problem.



See List.toArray(T)




... If the list fits in the specified array, it is returned therein.




i.e. you are copying into the original array, not creating a new one, so your arrays never actually decrease in size.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 13 at 14:30









OldCurmudgeon

51.2k1284167




51.2k1284167












  • Also sort(temp1); sort(temp2); should be temp1=sort(temp1); temp2=sort(temp2);
    – Eugen Covaci
    Nov 13 at 14:37










  • And (array.length/2) - 1 equals -1 for array.length =1
    – Eugen Covaci
    Nov 13 at 14:40


















  • Also sort(temp1); sort(temp2); should be temp1=sort(temp1); temp2=sort(temp2);
    – Eugen Covaci
    Nov 13 at 14:37










  • And (array.length/2) - 1 equals -1 for array.length =1
    – Eugen Covaci
    Nov 13 at 14:40
















Also sort(temp1); sort(temp2); should be temp1=sort(temp1); temp2=sort(temp2);
– Eugen Covaci
Nov 13 at 14:37




Also sort(temp1); sort(temp2); should be temp1=sort(temp1); temp2=sort(temp2);
– Eugen Covaci
Nov 13 at 14:37












And (array.length/2) - 1 equals -1 for array.length =1
– Eugen Covaci
Nov 13 at 14:40




And (array.length/2) - 1 equals -1 for array.length =1
– Eugen Covaci
Nov 13 at 14:40












up vote
0
down vote













Your conditional are not good enough, you get infinite sort call on your arrays.



At least you should include array of size equals to 2 :



if(array.length <= 2)


In addition, your copy method must be improved.



Anyway, copy/paste your full stack trace please.






share|improve this answer























  • can you access the google docs in the question?
    – Natalo77
    Nov 13 at 14:27










  • Yes I do, and it confirms calling endlessly your sort method.
    – Bsquare
    Nov 13 at 14:32















up vote
0
down vote













Your conditional are not good enough, you get infinite sort call on your arrays.



At least you should include array of size equals to 2 :



if(array.length <= 2)


In addition, your copy method must be improved.



Anyway, copy/paste your full stack trace please.






share|improve this answer























  • can you access the google docs in the question?
    – Natalo77
    Nov 13 at 14:27










  • Yes I do, and it confirms calling endlessly your sort method.
    – Bsquare
    Nov 13 at 14:32













up vote
0
down vote










up vote
0
down vote









Your conditional are not good enough, you get infinite sort call on your arrays.



At least you should include array of size equals to 2 :



if(array.length <= 2)


In addition, your copy method must be improved.



Anyway, copy/paste your full stack trace please.






share|improve this answer














Your conditional are not good enough, you get infinite sort call on your arrays.



At least you should include array of size equals to 2 :



if(array.length <= 2)


In addition, your copy method must be improved.



Anyway, copy/paste your full stack trace please.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 13 at 14:32

























answered Nov 13 at 14:14









Bsquare

1,9801625




1,9801625












  • can you access the google docs in the question?
    – Natalo77
    Nov 13 at 14:27










  • Yes I do, and it confirms calling endlessly your sort method.
    – Bsquare
    Nov 13 at 14:32


















  • can you access the google docs in the question?
    – Natalo77
    Nov 13 at 14:27










  • Yes I do, and it confirms calling endlessly your sort method.
    – Bsquare
    Nov 13 at 14:32
















can you access the google docs in the question?
– Natalo77
Nov 13 at 14:27




can you access the google docs in the question?
– Natalo77
Nov 13 at 14:27












Yes I do, and it confirms calling endlessly your sort method.
– Bsquare
Nov 13 at 14:32




Yes I do, and it confirms calling endlessly your sort method.
– Bsquare
Nov 13 at 14:32


















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.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • 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%2f53282765%2fgeneric-mergesort-java-implementation-stack-overflow-error%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

Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

ComboBox Display Member on multiple fields

Is it possible to collect Nectar points via Trainline?