排序 - 简单选择排序

前面我们提到过冒泡排序的非标准版,



用的是自上而下,每一个元素都与其它元素进行比较,如果前面大于后面的,则交换它们的值,


那此时就会出现一个性能上的问题,


因为在第二层循环体内,如果发现前面的元素大于后面的元素,就会交换它们的值。



而我们知道,二层循环体执行结束后的意义就是讲最小值放到前面,至于后面数值的顺序,它的排列时无意义的。


我们在后面的循环中才会将其排序。


所以说呢,我们有没有办法,将循环体中的最小值找到,放到一层循环的位置上。不久可以了吗?



简单选择排序就可以帮我们实现这个目的

void SelectSort(SqList *L){
       int i,j,min;
       for(i=1;i<L->length;i++){
            min = i;
            for(j=1;j<L->length;j++){
                 if(L->r[min]>L->r[j]){
                         min = j;
                 }
            }
           if(i!=min){
                 swap(L,i,min);
           }
       }
}

代码中,我们用一个变量min 来 代替i的初始值,然后在二层for循环体内,如果找到比min位置中还小的值,就将那个位置赋值给min。


这样,在二层循环体结束之后,如果判断当前的min下标和初始的下标如同,则代表改动过下标min的值,此时,交换i和min的位置上的值。


 下面来例子说明了,简单选择排序和冒泡排序非标准版在性能上的区别



如果我们需要排序的序列是{9,1,5,8,3,7,4,6,2}


对于从1循环到8,当i是1时,


L.r[i] = 9 ,min 开始是1,然后与j=2到9比较 L.r[min] 与L.r[j]的大小,因为j=2是最小,所以min=2.


最终交换了L.r[2]和L.r[1]的值。 


注意,这里比较了8次,却只交换数据操作一次。



当i=2是,L.r[i] = 9, min = 2 经过比较,min=9,交换L.r[min]与L.r[i]的值。这样就找到了第二个位置的关键字。



如果此时,我们用的是冒泡排序标准版,那么9和5会交换,5和3会交换,3和2会交换,一共要交换3次。


这样,我们就了解了它们在性能上的差异了。



下面给出java版的代码:

public class TestBubbleSort0 {
    public static void main(String args[]) {
        int a[] = {43, 54, 12, 65, 24, 123, 65, 42, 56, 221};
        int min;
        for(int i=0;i<a.length-1;i++){
            min = i;
            for(int j=i+1;j<=a.length-1;j++){
                 if(a[min]>a[j]){
                     min = j;
                 }
            }
            if(i!=min){
                bubbleSort0(a, i, min);
            }
        }

        for (int i = 0; i < a.length ; i++) {
            System.out.print(a[i] + " ");

        }

    }

    static void bubbleSort0(int a[], int i, int j) {
        int temp;
        temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
}
 

猜你喜欢

转载自alan-hjkl.iteye.com/blog/1580043
今日推荐