title: 重整算法第二天:選擇排序
date: 2019-04-10
tags: 算法
重整算法第二天:選擇排序
選擇排序的算法是這樣的:
首先,找到數組中最小的那個數,其次,將它和數組的第一個元素交換位置(如果第一個元素就是最小元素,那麼他就和自己交換)。再次,在剩下的元素中找到最小的元素,將它與數組的第二個元素交換位置,如此往復,直到將整個數組排序。
選擇排序實質上是在不斷的選擇剩餘元素之中的最小者。
選擇排序的內循環只是在比較當前元素與目前已知的最小元素(以及將當前索引加一和檢查是否代碼越界)。交換元素的代碼寫在內循環之外,每次交換都能排定一個元素,因此交換的總次數是N,所以算法的時間效率取決於比較的次數。
對於長度爲N的數組,選擇排序需要大約N2/2次比較和N次交換
總的來說,排序是一種很容易理解和實現的簡單排序算法,它有兩個很鮮明的特點:
運行時間和輸入無關。爲了找出最小的元素而掃描一遍數組並不能成爲下一遍掃描提供什麼信息。這種性質在某些情況下是缺點。
數據移動是最少的。每次交換都會改變兩個數組的元素的值,因此選擇排序用了N次交換—交換次數和數組的大小是線性關係。其他的任何算法都不具備這個特徵(大部分的增長數量級都是線性對數或是平方級別的)
排序主要代碼,按照之前的模板來寫的話,如下:
package com.lagoon.sort;
/**
* @Author WinkiLee
* @Date 2019/4/10 19:49
* @Description
*/
public class SelectSort {
public static void sort(Comparable[] a){
/**
* 算法編寫區域
*/
//將a[]按升序排列
int N=a.length;
for (int i=0;i<N;i++){
//將a[i]與a[i+1..N]中最小元素交換
//最小元素索引
int min=i;
for (int j=i+1;j<N;j++){
if (less(a[j],a[min])){
min=j;
}
}
exch(a,i,min);
}
}
/**
* 比較大小
* @param v
* @param w
* @return false or true
*/
private static boolean less(Comparable v,Comparable w){
return v.compareTo(w)<0;
}
/**
* 交換數
* @param a
* @param i
* @param j
*/
private static void exch(Comparable[] a,int i,int j){
Comparable t=a[i];
a[i]=a[j];
a[j]=t;
}
/**
* 打印結果
* @param a
*/
private static void show(Comparable[] a){
//在單行中打印數組
for (int i=0;i<a.length;i++){
System.out.print(a[i]+"");
}
System.out.println("");
}
/**
* 測試元素數組是否有序
* @param a
* @return true or false
*/
public static boolean isSorted(Comparable[] a){
//測試元素數組是否有序
for (int i=1;i<a.length;i++){
if (less(a[i],a[i-1])){
return false;
}
}
return true;
}
/**
* main方法及測試
* @param args
*/
public static void main(String[] args) {
Comparable[] a ={6,4,1,3,5,9,7,8,2};
Comparable[] b ={'a','e','w','p','s','b','q'};
sort(a);
sort(b);
show(a);
show(b);
}
}
測試結果如下