选择排序(Selection Sort)原理及Java实现

选择排序(Selection Sort )分为两种 简单选择排序(Simple Selection Sort) 和树形选择排序。


简单选择排序(Simple Selection Sort):

简单选择排序类似于冒泡排序(Bubble Sort) ,每次都会在剩下的元素集合中选择出一个最值出来填充到当前位置。唯一的区别是,冒泡排序在每次发现比当前值小于(或大于)时,都会交换元素的位置, 而 简单选择排序是选择剩余元素中的最值和当前位置交换数据。

比如对于元素集合R={37, 40, 38, 42, 461, 5,  7, 9, 12} 

在第一趟排序中:37直接和5交换, 形成新的序列 R1={5,40,38,42,461,37,7,9,12}

在第二趟排序中:40直接和7交换, 形成新的序列 R2={5,7,38,42,461,37,40,9,12}

以此类推,直到最后一个元素(注意:在第二趟排序中,38比42小,但是他们并没有交换数据)。

以下是简单选择排序的一个Java实现版本:

public static void selectionSort(int[] data) {
        if (data == null || data.length <= 1)
            return;
        int i, j, value, minPos, len = data.length;
        int outer = len - 1, tmp;
        for (i = 0; i < outer; i++) {
            value = data[i];
            minPos = -1;
            for (j = i + 1; j < len; j++) {
                if (data[j] < value) {
                    minPos = j;
                    value = data[j];
                }
            }
            if (minPos != -1) {
                tmp = data[i];
                data[i] = value;
                data[minPos] = tmp;
            }
            
//            for (int k = 0; k < len; k++) {
//                System.out.print(data[k] + " , ");
//            }
//            System.out.println();
        }
    }

    public static void main(String[] args) {
        int[] coll = {
                37, 40, 38, 42, 461, 5,  7, 9, 12
        };
        selectionSort(coll);
        for (int i = 0; i < coll.length; i++) {
            System.out.print(coll[i] + " , ");
        }
    }

树选择排序(Tree Selection Sort)

树选择排序算法相对于简单选择排序来说是典型的以空间换时间的算法。其思想是对待排序的 N 个元素 , 构造出相对较小的 (n+1)/2个数,然后再构造出相对较小的[n+1]/4个数,直到只有一个元素为止。构造成一个完全二叉树。

排序的时候,那个元素就是最小的,取出该最小元素,将该元素替换为"最大值",再调整完全二叉树。

下面是树形选择排序的一个Java实现版:

public static void treeSelectionSort(int[] data) {
        if (data == null || data.length <= 1)
            return;
        int len = data.length , low = 0 , i , j;
        // add Auxiliary Space
        int[] tmp = new int[2*len -1];
        int tSize = tmp.length;
        //construct a tree
        for(i =len-1 , j=tmp.length-1;i >=0 ;i--,j--){
            tmp[j]=data[i];
        }
        for(i = tSize -1 ; i > 0 ; i-=2){
            tmp[(i-1)/2] = tmp[i] > tmp[i-1]? tmp[i-1]:tmp[i];
        }
        //end
        //remove the minimum node.
        while(low < len){
            data[low++] = tmp[0];
            for(j=tSize-1;tmp[j]!=tmp[0];j--);
            tmp[j] = Integer.MAX_VALUE;
            while(j > 0){
                if(j%2 == 0){  //如果是右节点
                    tmp[(j-1)/2] = tmp[j] > tmp[j-1]?tmp[j-1]:tmp[j];
                    j = (j-1)/2;
                }else{  //如果是左节点
                    tmp[j/2]=tmp[j] > tmp[j+1]? tmp[j+1]:tmp[j];
                    j = j/2;
                }
            }
        }
    }
在构造完全二叉树的时候对 N 个元素的集合, 需要 2*N -1 个辅助空间。

代码:

 while(j > 0){
                if(j%2 == 0){  //如果是右节点
                    tmp[(j-1)/2] = tmp[j] > tmp[j-1]?tmp[j-1]:tmp[j];
                    j = (j-1)/2;
                }else{  //如果是左节点
                    tmp[j/2]=tmp[j] > tmp[j+1]? tmp[j+1]:tmp[j];
                    j = j/2;
                }
            }
则实现递归的构造新集合中的最小值。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值