【问题标题】:selection sort method for array数组的选择排序方法
【发布时间】:2014-01-17 20:25:11
【问题描述】:

我有一个从网站上得到的关于选择排序的方法,我需要检查它是如何工作的:

import java.util.Arrays;

public class SelectionSort {
public static void selectionSort(int[] data, int low, int high) {
    if (low < high) {
        swap(data, low, findMinIndex(data, low));
        selectionSort(data, low + 1, high);
    }
}

public static void swap(int[] array, int index1, int index2) {
    int tmp = array[index1];
    array[index1] = array[index2];
    array[index2] = tmp;
}

public static int findMinIndex(int[] data, int index) {
        int minIndex;
        if (index == data.length - 1)
        return index;
        minIndex = findMinIndex(data, index + 1);
        if (data[minIndex] < data[index])
        return minIndex;
        else
        return index;
}



public static void main (String[] args) {
    int[] numbers = {3, 15, 1, 9, 6, 12, 21, 17, 8}; 
    SelectionSort.selectionSort(numbers, 0, numbers.length);
    System.out.println(Arrays.toString(numbers));
}
}

你能帮我理解为什么 int high 得到数组的最后一个索引吗?如何?

【问题讨论】:

  • 能否请您显示调用 selectionSort 的 main() 方法的代码,然后尝试重新表述您的问题?完全不清楚你在问什么,所以很难提供帮助。
  • 我更正了问题中的代码,它遗漏了一些行。现在问题太明显了。

标签: java arrays recursion


【解决方案1】:

在这个特定的代码中...

findMinIndex 将给定索引中的元素与它前面的所有元素(具有更高索引的元素)进行比较,直到数组的最后一个元素。

所以如果你有一个数组:

int[] a = { 7, 4, 2, 6 };

然后你调用findMinIndex(a, 0);,它会首先检查索引0 之后是否有一个元素。这就是这部分的作用index == data.length - 1。如果后面没有元素,它将简单地返回它传递的index。但显然在索引 0 之后有一个元素,因为数组的长度为 4。

现在我们已经确认index 之后有元素,是时候获取index 之后的smallest 元素的索引了。这样,我们可以将index 处的元素与其前面的所有元素进行比较,以查看在indexarray.length - 1(包括)范围内哪个元素最小。这是通过递归实现的:

minIndex = findMinIndex(data, index + 1);

所以接下来的几个电话会是这样的:

findMinIndex(data, 1);
// is there an element after 1? There is. So we end up calling findMinIndex again...

findMinIndex(data, 2); // is there an element after 2? Yes. Recurse...

findMinIndex(data, 3); // is there an element after 3? No. That's the end of the array

// remember this part? it's used now to finally terminate the recursion
if (index == data.length - 1)
    return index; // this equals 3

现在递归调用开始展开。

// index == 2 because the 2nd to last index is 2. remember our array has length 4 and indices 0-3.
minIndex = 3; // this is the index of the last element
if (data[3] < data[2]) { // look at our array 'a', is 6 less than 2?
    return 3; // No it is not. so this is not returned
} else {
    return 2; // we end up return the index (2) of the smaller element (2)
}

它再次放松。

// index == 1
minIndex = 2; // we compared 2 and 3 and found that the element at index 2 was smaller
if (data[2] < data[1]) { // is 2 less than 4?
    return 2; // yes, this is returned because the element at index 2 is less than the element at index 1
} else {
    return 1; // false!
}

再来一次。

// index == 0 this is our original call! when we said findMinIndex(a, 0);
minIndex = 2;
if (data[2] < data[0]) { // is 2 less than 7?
    return 2; // yes it is
} else {
    return 0; // false!
}

最后,该方法将返回 2。这是因为(包括)索引 0 之后的所有元素,索引为 2 的元素是最小的。

现在让我们看看selectionSort。首次调用时,需要使用这种格式:

selectionSort(a, 0, 4); // where 4 is the length of the array

这个函数也使用递归。 swap 方法是不言自明的(它在 2 个不同的索引处交换元素)。现在让我们来看看递归调用:

if (0 < 4) { // True of course
    swap(a, 0, findMinIndex(a, 0));
    selectionSort(data, 0 + 1, 4);
}

记住我们发现0(含)之后的最小元素的索引为2。所以上面的代码可以替换为:

if (0 < 4) { // True of course
    swap(a, 0, 2);
    selectionSort(data, 0 + 1, 4);
}

这会将我们的数组更改为{2, 4, 7, 6},因为我们交换了索引 0 和索引 2 处的元素。请注意索引 0 现在是数组中值为 2 的最小元素。

现在再次调用selectionSort 以确保数组按从小到大的顺序排列。下一个调用将如下所示:

// low == 1 and high == 4
if (1 < 4) { // true
    swap(a, 1, findMinIndex(data, 1));
    selectionSort(a, 1 + 1, 4);
}

记住我们的数组现在是{2, 4, 7, 6}。这意味着索引 1 之后的最小元素(值为 4)实际上只是 4。所以上面的代码将等于:

// low == 1 and high == 4
if (1 < 4) { // true
    swap(a, 1, 1);
    selectionSort(a, 1 + 1, 4);
}

在这种情况下,交换没有任何作用。现在再次递归调用该方法。

// low == 2 and high == 4
if (2 < 4) { // true
    swap(a, 2, findMinIndex(data, 2));
    selectionSort(a, 2 + 1, 4);
}

我们的数组在上次交换时没有改变。索引 2(含)之后的最小元素是 6,其索引为 3。这意味着我们上面的代码等于:

// low == 2 and high == 4
if (2 < 4) { // true
    swap(a, 2, 3);
    selectionSort(a, 2 + 1, 4);
}

现在我们的数组变成了{ 2, 4, 6, 7 }。万岁,这是从最小到最大的顺序!但这不是它结束的地方。还有另一个递归调用只是为了确保它确实是有序的。

// low == 3 and high == 4
if (3 < 4) { // true
    swap(a, 3, findMinIndex(data, 3));
    selectionSort(a, 3 + 1, 4);
}

还记得在findMinIndex 中,它会检查给定索引之后是否有任何元素?索引 3 之后没有元素,所以它只会返回 3。这意味着上面的代码等于:

// low == 3 and high == 4
if (3 < 4) { // true
    swap(a, 3, 3);
    selectionSort(a, 3 + 1, 4);
}

这个交换什么都不做。如您所见,还有另一个递归调用!这将是最后一个。

// low == 4 and high == 4
if (4 < 4) { // false, 4 is not less than 4
    swap(a, 4, findMinIndex(a, 4)); // none of this happens
    selectionSort(a, 4 + 1, 4); // no recursion
}
// finally returns void

结束。

与递归相比,使用循环更容易理解选择排序。

【讨论】:

    【解决方案2】:

    是数组的大小,用来知道什么时候结束。

    每个周期: 首先:检查是否有任何元素和索引高于低(低从 0 开始)较低,如果是这种情况,则交换它们。 二:加低

    当低不低于高(数组大小)时停止。

    参见选择排序的定义:

    http://en.wikipedia.org/wiki/Selection_sort

    【讨论】:

      【解决方案3】:

      对于正在寻找另一种使用递归进行选择排序的方法的人,这里有一种方法。

      //the method that will be called to sort the array recursively
      public static void selectionSort(double[] arr) {
          selectionSort(arr, 0);
      }
      
      //this is a recursive helper method.
      //arr is the array to be sorted and index is the current index in
      //the array which will be swapped with the smallest value in the
      //remaining part of the array
      private static void selectionSort(double[] arr, int index) {
          //if index has reached the second to last value, there are
          //no more values to be swapped
          if (index < arr.length - 1) {
              //let index, at first, be the index at which the smallest element is located
              int smallestIndex = index;
              //find the smallest entry in the array from i=index to i=index.length - 1
              for (int i = index + 1; i < arr.length; i++) {
                  //if the element at i is smaller than the element at smallestIndex, then update the value of smallestIndex
                  if (arr[i] < arr[smallestIndex]) {
                      smallestIndex = i;
                  }
              }
              //swap the elements of arr[smallestIndex] and arr[index]
              double t = arr[index];
              arr[index] = arr[smallestIndex];
              arr[smallestIndex] = t;
              selectionSort(arr, index + 1);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2015-12-03
        • 1970-01-01
        • 2016-08-15
        • 2015-05-20
        • 2023-03-15
        • 2013-08-30
        • 1970-01-01
        • 2018-04-28
        相关资源
        最近更新 更多