排序: 选择排序

1. 基本原理

将待排序的元素分为已排序(初始为空)和未排序两组,依次将未排序的元素中值最小的元素放入已排序的组中。

 

直接选择排序简单直观,但性能略差;堆排序是一种较高效的选择排序方法,但实现起来略微复杂。

 

2. 直接选择排序

基本过程为:

  • 在一组元素R[i]到R[n]中选择具有最小关键码的元素
  • 若它不是这组元素中的第一个元素,则将它与这组元素中的第一个元素对调。
  • 除去具有最小关键字的元素,在剩下的元素中重复第(1)、(2)步,直到剩余元素只有一个为止。

 

 

3. 代码实现

  1 package com.windy.sort;
  2 
  3 import java.util.Arrays;
  4 
  5 import org.junit.Test;
  6 
  7 public class SelectSort {
  8 
  9     class DataWrap implements Comparable<DataWrap> {
 10         int data;
 11         String flag;
 12 
 13         public DataWrap(int data, String flag) {
 14             this.data = data;
 15             this.flag = flag;
 16         }
 17 
 18         @Override
 19         public String toString() {
 20             return data + flag;
 21         }
 22 
 23         @Override
 24         public int compareTo(DataWrap dw) {
 25 
 26             return this.data > dw.data ? 1 : (this.data == dw.data ? 0 : -1);
 27 
 28         }
 29     }
 30 
 31     @Test
 32     public void test1() {
 33 
 34         DataWrap[] dw = new DataWrap[] { 
 35                 new DataWrap(-9, ""), 
 36                 new DataWrap(1, ""),
 37                 new DataWrap(-47, "*"),
 38                 new DataWrap(1246, ""), 
 39                 new DataWrap(758, ""), 
 40                 new DataWrap(-123, ""), 
 41                 new DataWrap(5, ""),
 42                 new DataWrap(638, ""), 
 43                 new DataWrap(-47, ""), 
 44                 new DataWrap(5, "*")
 45                 };
 46 
 47         System.out.println("排序前:\n" + Arrays.toString(dw));
 48         selectSort(dw);
 49         System.out.println("排序后:\n" + Arrays.toString(dw));
 50     }
 51 
 52     @Test
 53     public void test2() {
 54         DataWrap[] dw = new DataWrap[] { 
 55                 new DataWrap(-9, ""), 
 56                 new DataWrap(1, ""),
 57                 new DataWrap(-47, "*"),
 58                 new DataWrap(1246, ""), 
 59                 new DataWrap(758, ""), 
 60                 new DataWrap(-123, ""), 
 61                 new DataWrap(5, ""),
 62                 new DataWrap(638, ""), 
 63                 new DataWrap(-47, ""), 
 64                 new DataWrap(5, "*")
 65                 };
 66 
 67         System.out.println("排序前:\n" + Arrays.toString(dw));
 68         selectSort2(dw);
 69         System.out.println("排序后:\n" + Arrays.toString(dw));
 70     }
 71 
 72     // 直接选择排序
 73     private static void selectSort(DataWrap[] dw) {
 74 
 75         int length = dw.length;
 76 
 77         System.out.println("排序中...");
 78 
 79         for (int i = 0; i < length - 1; i++) {
 80 
 81             for (int j = i + 1; j < length; j++) {
 82                 if (dw[i].compareTo(dw[j]) > 0) {
 83                     DataWrap temp;
 84                     temp = dw[i];
 85                     dw[i] = dw[j];
 86                     dw[j] = temp;
 87                 }
 88             }
 89 
 90             System.out.println(Arrays.toString(dw));
 91         }
 92 
 93     }
 94 
 95     /*
 96      * 直接选择排序改进版 用临时变量记录最小值的下标,而不是选择马上交换 在对比一轮结束之后,才选择交换
 97      */
 98     private static void selectSort2(DataWrap[] dw) {
 99         int length = dw.length;
100 
101         System.out.println("排序中...");
102         for (int i = 0; i < length - 1; i++) {
103             int min = i;
104 
105             for (int j = i + 1; j < length; j++) {
106                 // 用最小值去对比,而不是dw[i]
107                 if (dw[min].compareTo(dw[j]) > 0) {
108                     min = j;
109                 }
110             }
111 
112             DataWrap temp;
113             temp = dw[i];
114             dw[i] = dw[min];
115             dw[min] = temp;
116 
117             System.out.println(Arrays.toString(dw));
118         }
119 
120     }
121 
122 }
View Code

 

结果打印:

排序前:
[-9, 1, -47*, 1246, 758, -123, 5, 638, -47, 5*]
排序中...
[-123, 1, -9, 1246, 758, -47*, 5, 638, -47, 5*]
[-123, -47*, 1, 1246, 758, -9, 5, 638, -47, 5*]
[-123, -47*, -47, 1246, 758, 1, 5, 638, -9, 5*]
[-123, -47*, -47, -9, 1246, 758, 5, 638, 1, 5*]
[-123, -47*, -47, -9, 1, 1246, 758, 638, 5, 5*]
[-123, -47*, -47, -9, 1, 5, 1246, 758, 638, 5*]
[-123, -47*, -47, -9, 1, 5, 5*, 1246, 758, 638]
[-123, -47*, -47, -9, 1, 5, 5*, 638, 1246, 758]
[-123, -47*, -47, -9, 1, 5, 5*, 638, 758, 1246]
排序后:
[-123, -47*, -47, -9, 1, 5, 5*, 638, 758, 1246]

 

4. 算法效率分析

  • 算法的时间效率:无论初始状态如何,在第i趟排序中选择最小关键码的元素,需做n-i次比较,因此总的比较次数为:

        

 

  • 算法的空间效率:空间效率很高,只需要一个附加程序单元用于交换,其空间效率为O(1)

 

  • 算法的稳定性:不稳定
posted @ 2017-03-24 00:27  fengze  阅读(116)  评论(0编辑  收藏  举报