有一种工作合并排序,但不完全,有人可以告诉我我做错了什么?

时间:2013-04-22 13:23:26

标签: java arrays sorting

首先,我想从我的方法背后开始。我的想法是,我将要么输入一个偶数或奇数的数组。该数组将在2D数组中分解原始数组的长度,每个索引具有一个大小为1的数组。然后我将继续合并索引。这适用于长度为2,4,8,16的长度。现在,我不得不编辑我的方法,因为3,5,6,7不起作用。现在,我的问题是即使它们有效,但并非所有情况都有效。例如,长度为25不能正确返回。以下是我的代码:

/**
* A method to perform a merge sort
* @param array The array being fed in
*/
public static int[] mergeSort(int[] array)
{
  if (array.length == 1)
  {
     return array;
  }

  int size = array.length;
  int[][] miniArrayList = new int[size][1];

  for (int index = 0; index < array.length; index++)
  {
     miniArrayList[index][0] = array[index];
  }

  while (miniArrayList.length > 1)
  {
     if (miniArrayList.length % 2 == 0)
     {
        miniArrayList = mergeEven(miniArrayList);
     }
     else
     {
        miniArrayList[0] = mergeOdd(miniArrayList);
     }
  }
  return miniArrayList[0];
}

我对上述方法的想法是我输入一个数组,它将其分解,然后它一点一点地合并数组,直到我有一个大小为1的排序数组。上面的方法调用以下方法: / p>

private static int[][] mergeEven(int[][] array)
{
  int[][] tempSortList = new int[array.length / 2][];
  int tempIndex = 0;
  for (int index = 0; index < array.length; index += 2)
  {
     tempSortList[tempIndex] = merge(array[index], array[index + 1]);
     if (tempIndex != tempSortList.length)
     {
        tempIndex++;
     }
  }
  array = tempSortList;
  return array;
}

private static int[] mergeOdd(int[][] array)
{
  /**
   * The concept is to call the even merge method on the even part
   * of the list and then once I get to one array, I merge that array
   * with the extra array.
   */
  int[][] localArray = new int[array.length - 1][1];
  int[][] extra = new int[1][1];

  for (int index = 0; index < localArray.length; index++)
  {
     localArray[index][0] = array[index][0];
  }

  extra[0][0] = array[array.length - 1][0];

  int[][] tempSortList = new int[localArray.length / 2][];
  int tempIndex = 0;
  for (int index = 0; index < localArray.length; index += 2)
  {
     tempSortList[tempIndex] = merge(localArray[index], localArray[index + 1]);
     if (tempIndex != tempSortList.length)
     {
        tempIndex++;
     }
  }
  localArray = tempSortList;

  return localArray[0] = merge(localArray[0], extra[0]);
}

这是非常自我解释,但以防万一。上面的方法排序不同,因为数组是奇数或偶数。最后,这些方法调用实际的合并方法(我认为这是有效的):

/**
* A merge method to merge smaller arrays to bigger
* arrays
* @param arrayOne The first array being fed in
* @param arrayTwo The second array being fed in
* @return A new integer array which is the sum of the
* length of the two arrays
*/
private static int[] merge(int[] arrayOne, int[] arrayTwo)
{
  /*
   * To make a proper method that deals with odd array sizes
   * look into seeing if it odd, only merging length of the array -1
   * and then once that is all merged merge that array with the last part of the array
   */
  //Creating the size of the new subarray
  int[] mergedArray;

  if (arrayOne.length % 2 == 0 && arrayTwo.length % 2 == 0)
  {
     int size = arrayOne.length;
     int doubleSize = 2 * size;
     mergedArray = new int[doubleSize];

     //Positions of each array
     int posOne = 0;
     int posTwo = 0;
     int mergeIndex = 0;

     while (posOne < size && posTwo < size)
     {
        if (arrayOne[posOne] < arrayTwo[posTwo])
        {
           mergedArray[mergeIndex] = arrayOne[posOne];
           mergeIndex++;
           posOne++;
        }
        else
        {
           mergedArray[mergeIndex] = arrayTwo[posTwo];
           mergeIndex++;
           posTwo++;
        }
     }

     if (posOne == size)
     {
        for (int rest = posTwo; rest < size; rest++)
        {
           mergedArray[mergeIndex] = arrayTwo[rest];
           mergeIndex++;
        }
     }
     else
     {
        for (int rest = posOne; rest < size; rest++)
        {
           mergedArray[mergeIndex] = arrayOne[rest];
           mergeIndex++;
        }
     }

  }
  else
  {
     int arrayOneSize = arrayOne.length;
     int arrayTwoSize = arrayTwo.length;
     int newArraySize = arrayOneSize + arrayTwoSize;
     mergedArray = new int[newArraySize];

     //Position in each array
     int posOne = 0;
     int posTwo = 0;
     int mergeIndex = 0;

     while (posOne < arrayOneSize && posTwo < arrayTwoSize)
     {
        if (arrayOne[posOne] < arrayTwo[posTwo])
        {
           mergedArray[mergeIndex] = arrayOne[posOne];
           mergeIndex++;
           posOne++;
        }
        else
        {
           mergedArray[mergeIndex] = arrayTwo[posTwo];
           mergeIndex++;
           posTwo++;
        }
     }
     if (posOne == arrayOneSize)
     {
        mergedArray[mergeIndex] = arrayTwo[posTwo];
        mergeIndex++;
     }
     else
     {
        for (int rest = posOne; rest < arrayOneSize; rest++)
        {
           mergedArray[mergeIndex] = arrayOne[rest];
           mergeIndex++;
        }
     }

  }

  return mergedArray;
}

所以我的问题是,我正确输入的任何数组大小,它只适用于某些大小。我已经完成了一些阅读文章,但我的实现与大多数我看到的非常不同,这就是我在这里发布的原因。我不想只复制一个工作的,我想了解我做错了什么,所以我可以解决它。在此先感谢帮助人员!

2 个答案:

答案 0 :(得分:0)

您的问题符合merge的逻辑。通过使用

int size = arrayOne.length;

你假设两个数组都有相同的长度。但是,在不均匀的情况下,并非所有阵列都具有相同的长度。

将其更改为两种不同的尺寸,代码应该没问题。

答案 1 :(得分:0)

更大的问题是你的算法过于复杂,更不用说对于非常大的数组来说效率低了。

我假设你这是一个学术练习,但每当你开始工作时,请查看java.util.Arrays.mergeSort(私有方法)作为例子。