文 | 莫若吻
1.簡介
排序就是算法。
? 選擇排序(Selection sort)是一種簡單直觀的排序算法。
選擇排序是不穩(wěn)定的排序方法。
? eg:序列[9,9, 1]第一次就將第一個[9]與[1]交換,導(dǎo)致第一個9挪動到第二個9后面
Note:一般面試的時候才會用到選擇、冒泡排序。
2.原理
選擇排序的工作原理是**每一次從待排序的數(shù)據(jù)元素中選出最小(或最大)的一個元素,存放在序列的起始位置,直到全部待排序的數(shù)據(jù)元素排完。 **
3.原理過程圖
內(nèi)循環(huán)結(jié)束一次,最值出現(xiàn)頭角標(biāo)位置上。(原理過程如下圖)
4.時間復(fù)雜度
簡單選擇排序的比較次數(shù)與序列的初始排序無關(guān)。 假設(shè)待排序的序列有 n 個元素,選擇排序的賦值操作介于 0 和 3 (n - 1) 次之間; 則比較次數(shù) 永遠(yuǎn)都是n (n- 1) / 2; 而移動次數(shù)(即:交換操作)與序列的初始排序有關(guān),介于 0 和 (n - 1) 次之間。當(dāng)序列正序時,移動次數(shù)最少,為 0。當(dāng)序列反序時,移動次數(shù)最多,為n - 1 次;逆序交換n/2次。綜上,簡單選擇排序的時間復(fù)雜度為 O(n2)。
選擇排序的移動次數(shù)比冒泡排序少多了,由于交換所需CPU時間比 比較所需的CPU時間多,n值較小時,選擇排序比冒泡排序快。
5.性能分析 (穩(wěn)定性)
選擇排序的時間復(fù)雜度為O(n2),由于每次選擇僅考慮某一位置上的數(shù)據(jù)情況,可能會破壞之前數(shù)據(jù)的相對位置,因此它是一種不穩(wěn)定的排序方法。
6.選擇排序有兩個重要特點(diǎn):
1)運(yùn)行時間和輸入無關(guān)
即不論數(shù)組的初始狀態(tài)的有序程度,選擇排序的比較次數(shù)都沒有變化。考慮到比較次數(shù)與元素個數(shù)的關(guān)系是n (n- 1)/ 2,所以當(dāng)一個已經(jīng)比較有序的數(shù)組使用選擇排序會很不劃算。
2)數(shù)據(jù)的移動操作最少
移動操作次數(shù)是一個常量,最多為n-1,其他的算法都不具備這個特征。
7.選擇排序與冒泡排序哪個效率更高?
選擇排序、冒泡排序都用for(for(if))結(jié)構(gòu)語句。一般選擇排序效率會更高一些。
自我總結(jié)分析原因:(更詳細(xì)情況請參考上面選擇排序的時間復(fù)雜度)
冒泡排序的思想為每一次排序過程,通過相鄰元素的交換,將當(dāng)前沒有排好序中的最大(小)移到數(shù)組的最右(左)端。而選擇排序的思想也很直觀:每一次排序過程,我們獲取當(dāng)前沒有排好序中的最大(小)的元素和數(shù)組最右(左)端的元素交換,循環(huán)這個過程即可實(shí)現(xiàn)對整個數(shù)組排序。
同樣數(shù)據(jù)的情況下,兩種算法的循環(huán)次數(shù)是一樣的,但選擇排序只有0到1次交換,而冒泡排序只有0到n次交換 。而影響我們算法效率的主要部分是循環(huán)和交換,顯然,次數(shù)越多,效率就越差。選擇排序的平均時間復(fù)雜度比冒泡排序的稍低。所以相比較而言選擇排序效率會更高一些。
8.示例代碼(Java)
對給指定數(shù)組進(jìn)行排序:{5,1,6,4,2,8,9}
核心代碼:
/*
選擇排序。
內(nèi)循環(huán)結(jié)束一次,最值出現(xiàn)頭角標(biāo)位置上。
*/
public static void selectSort(int[] arr)
{
for (int x=0; x<arr.length-1 ; x++)
{
for(int y=x+1; y<arr.length; y++)
{
if(arr[x]>arr[y]) //缺點(diǎn):性能低。
{
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
}
}```
__詳細(xì)代碼:__
? (注:大家可以自行運(yùn)行結(jié)果查看)
import java.util.*;
class ArraySort
{
public static void main(String[] args)
{
int[] arr = {5,1,6,4,2,8,9};
//排序前;
printArray(arr);
//選擇排序
selectSort(arr);
//冒泡排序
//bubbleSort(arr);
//排序后:
printArray(arr);
//Arrays.sort(arr); //java中已經(jīng)定義好的一種排序方式。開發(fā)中,對數(shù)組排序。要使用該句代碼。
}
/*
選擇排序。
內(nèi)循環(huán)結(jié)束一次,最值出現(xiàn)頭角標(biāo)位置上。
*/
public static void selectSort(int[] arr)
{
for (int x=0; x<arr.length-1 ; x++)
{
for(int y=x+1; y<arr.length; y++)
{
if(arr[x]>arr[y]) //缺點(diǎn):性能低。
{
swap(arr,x,y);
}
}
}
}
/*
無論什么排序。都需要對滿足條件的元素進(jìn)行位置置換。
所以可以把這部分相同的代碼提取出來,單獨(dú)封裝成一個函數(shù)。
*/
public static void swap(int[] arr,int a,int b)
{
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
/*
排序顯示格式
*/
public static void printArray(int[] arr)
{
System.out.print("[");
for(int x=0; x<arr.length; x++)
{
if(x!=arr.length-1)
System.out.print(arr[x]+", ");
else
System.out.println(arr[x]+"]");
}
}
}
<br/>
***
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請必須注明出處,謝謝!
<br/>