我试图为类编写递归合并排序方法。当我尝试mergeSort(leftArr)
和mergeSort(rightArr)
时,我不断获得stackoverflow。为什么我没有工作的基本情况?
import java.util.Arrays;
public class SortingAlgorithms {
public static void mergeSort(int[] list){
int mid = list.length / 2;
int [] leftArr = new int [mid];
int [] rightArr;
if (mid % 2 == 0) {
rightArr = new int [mid];
}
else{
rightArr = new int [mid + 1];
}
if (leftArr.length < 2 && rightArr.length < 2){
list = mergeHelper(leftArr, rightArr);
}
// copying first half of array
for (int i = 0; i < mid; i++){
leftArr[i] = list[i];
}
// copying second half of array
int placeHolder = 0;
for (int i = mid; i < list.length; i++){
if (placeHolder < rightArr.length) {
rightArr[placeHolder] = list[i];
placeHolder++;
}
}
mergeSort(leftArr);
mergeSort(rightArr);
}
public static int[] mergeHelper(int[] leftArr, int[] rightArr){
int leftIndex = 0;
int rightIndex = 0;
int sortedArrayIndex = 0;
int[] newList = new int[leftArr.length + rightArr.length];
while (leftIndex < leftArr.length || rightIndex < rightArr.length){
if (leftIndex < leftArr.length && rightIndex < rightArr.length){
if(leftArr[leftIndex] > rightArr[rightIndex]){
newList[sortedArrayIndex] = rightArr[rightIndex];
rightIndex++;
sortedArrayIndex++;
}
else {
newList[sortedArrayIndex] = leftArr[leftIndex];
leftIndex++;
sortedArrayIndex++;
}
}
else if (leftIndex < leftArr.length && rightIndex == rightArr.length){
newList[sortedArrayIndex] = leftArr[leftIndex];
leftIndex++;
sortedArrayIndex++;
}
else if (rightIndex < rightArr.length && leftIndex == leftArr.length){
newList[sortedArrayIndex] = rightArr[rightIndex];
rightIndex++;
sortedArrayIndex++;
}
}
return newList;
}
public static void populateArray(int[] list){
for (int i = 0; i < list.length; i++){
list[i] = (int) ((Math.random() * 100));
}
}
public static void main(String[] args){
int [] list = new int [10];
populateArray(list);
System.out.println(Arrays.toString(list));
mergeSort(list);
System.out.println(Arrays.toString(list));
//proof that mergeHelper() works
// int[] left = {1,3,5,7,9};
// System.out.println(Arrays.toString(left));
// int[] right = {0,2,4,6,8};
// System.out.println(Arrays.toString(right));
// System.out.println(Arrays.toString(mergeHelper(left,right)));
}
}
答案 0 :(得分:2)
你的权利长度确定不好。校正:
rightArr = new int [list.length - mid];
答案 1 :(得分:0)
## This is a way to use merge sort in c#, with recursion. ##
static void Main(string[] args)
{
List<int> list = new List<int>();
int m = int.Parse(Console.ReadLine());
for (int i = 0; i < m; i++)
{
int p = int.Parse(Console.ReadLine());
list.Add(p);
}
Console.WriteLine(String.Join(",", MergeSort(list)));
}
static List<int> MergeSort(List<int> array)
{
List<int> output = new List<int>();
if (array.Count == 1)
{
return array;
}
if (array.Count == 2)
{
if (array[0] > array[1])
{
int a = array[1];
array[1] = array[0];
array[0] = a;
return array;
}
else
{
return array;
}
}
else
{
List<int> firstList = new List<int>();
List<int> secondList = new List<int>();
for (int i = 0; i < array.Count / 2; i++)
{
firstList.Add(array[i]);
secondList.Add(array[i + array.Count / 2]);
}
if (array.Count % 2 != 0)
{
secondList.Add(array[array.Count - 1]);
}
firstList = MergeSort(firstList);
secondList = MergeSort(secondList);
int k = 0;
int j = 0;
int size = firstList.Count + secondList.Count;
int markerFirst = firstList.Count;
int markerSecond = secondList.Count;
for (int i = 0; i < size; i++)
{
if (k == markerFirst)
{
output.Add(secondList[j]);
j++;
continue;
}
if (j == markerSecond)
{
output.Add(firstList[k]);
k++;
continue;
}
if (firstList[k] < secondList[j])
{
output.Add(firstList[k]);
k++;
}
else
{
output.Add(secondList[j]);
j++;
}
}
}
return output;
}
}
}
答案 2 :(得分:0)
您的代码存在一些问题:
1)在“mergeSort”方法中没有像下面的代码那样停止递归的条件。你收到stackoverflows,因为你的代码处于无限循环中。在“mergeSort”方法的第一行添加此代码。
if(list.length <= 1)
return;
2)修复“rightArr”大小......用你的代码运行这2次修正,但不进行排序。
int[] rightArr = new int [list.length - mid];
// if (mid % 2 == 0) {
// rightArr = new int[mid];
// } else {
// rightArr = new int[mid + 1];
// }
以更简单的方式遵循代码......
import java.util.Arrays;
public class MergeSort {
public static void main(String[] args) {
Integer[] itens = {2,6,4,9,1,3,8,7,0};
Integer[] tmp = new Integer[itens.length];
int left = 0;
int right = itens.length - 1;
mergeSort(itens, tmp, left, right);
System.out.println(Arrays.toString(itens));
}
private static void mergeSort(Integer[] itens, Integer[] tmpArray, int left, int right) {
if(itens == null || itens.length == 0 || left >= right){
return;
}
int midle = (left + right) / 2;
mergeSort(itens, tmpArray, left, midle);
mergeSort(itens, tmpArray, midle + 1, right);
merge(itens, tmpArray, left, midle + 1, right);
}
private static void merge(Integer[] itens, Integer[] tmpArray, int left, int right, int rightEnd) {
int leftEnd = right - 1;
int tmpIndex = left;
while (left <= leftEnd && right <= rightEnd){
if (itens[left] < itens[right] ){
tmpArray[tmpIndex++] = itens[left++];
} else {
tmpArray[tmpIndex++] = itens[right++];
}
}
while (left <= leftEnd) { // Copy rest of LEFT half
tmpArray[tmpIndex++] = itens[left++];
}
while (right <= rightEnd) { // Copy rest of RIGHT half
tmpArray[tmpIndex++] = itens[right++];
}
while(rightEnd >= 0){ // Copy TEMP back
itens[rightEnd] = tmpArray[rightEnd--];
}
}
}