我必须根据以下参数在Java中实现选择排序:


对SelectionSort实现一个变体,该变体在扫描列表时定位最小和最大元素,并将它们分别放置在列表的开头和结尾。在第一遍,扫描元素x0,...,xn-1;在第二遍中,扫描元素x1,...,xn-2;等等。


我正在向该方法传递大小为32的数组,并且在我打印该数组时未对其进行排序。我的代码有什么问题?

static void selectionSort() {
    scramble();
    int smallIndex = 0;  //index of smallest to test
    int largeIndex = array.length - 1;  //index of largest to test
    int small = 0;  //smallest
    int large;  //largest
    int smallLimit = 0;  //starts from here
    int largeLimit = array.length - 1;  //ends here
    int store;  //temp stored here
    int store2;

    for(int i = 0; i < array.length/2; i++) {  //TODO not working...
        small = array[smallLimit];
        large = array[largeLimit];
        for(int j = smallLimit; j <= largeLimit; j++) {
            if(array[j] < small) {
                smallIndex = j;
                small = array[j];
            }
            else if(array[j] > large) {
                largeIndex = j;
                large = array[j];
            }
        }
        store = array[smallLimit];
        store2 = array[smallIndex];
        array[smallLimit] = store2;
        array[smallIndex] = store;
        store = array[largeLimit];
        array[largeLimit] = array[largeIndex];
        array[largeIndex] = store;
        smallLimit++;
        largeLimit--;
    }
    print();
}

最佳答案

想想极端情况:在smallLimitlargeLimit处找到最大或最小项目时会发生什么。发生这种情况时,您会遇到两个问题:


未设置largeIndexsmallIndex。他们保持先前迭代的值。
将最小的项目交换到正确的位置可移动最大的项目。第二次交换将最小的物料移到最大的物料上,最大的物料最终移到随机位置。如果您发现难以看清的代码,请逐步检查纸上或调试器中的代码。


这些问题很容易解决。您可以遵循一些准则来避免此问题:


使用更少的活动部件。您始终可以使用small来获取smallIndex的值,如果您只是使用smallIndex,则不会存在不同变量失步的危险。
在尽可能小的范围内声明变量。如果smallIndex在循环体中声明并且不在编译器外部,则编译器会告诉您,有可能在交换之前未设置它。
破坏性更新(如此处的第一次交换)始终会使以前的计算过时。当您无法避免这种情况发生时,请寻找两个更新可以互相作用的方式。

10-06 13:40