排序算法六:選擇排序之簡單選擇排序


聲明:引用請注明出處http://blog.csdn.net/finish_dream/article/details/70231398


引言

之前已經講過排序算法系列的插入排序,交換排序。接下來這篇文章和下一篇文章主要講解選擇排序。


排序相關的基本概念

  • 排序:將一組雜亂無章的數據按一定的規律順次排列起來。

    • 數據表(data list):它是待排序對象的有限集合。
    • 排序碼(key):通常對象有多個屬性域,即多個數據成員組成,其中有一個屬性域,可用來區分對象,作為排序依據。該域即為排序
      碼,每個數據表用哪個屬性域作為排序碼,要視具體的應用需要而定。
  • 分類

    • 內排序:指在排序期間數據對象全部存放在內存的排序;
    • 外排序:指在排序期間全部對象個數太多,不能同時存放在內存,必須根據排序過程的要求,不斷在內、外存之間移動的排序。

排序的分析

排序算法的穩定性

如果在對象序列中有兩個對象r[i]和r[j] ,它們的排序碼k[i]==k[j] 。如果排序前后,對象r[i]和r[j] 的相對位置不變,則稱排序算法是穩定的;否則排序算法是不穩定的。

排序算法的評價

時間開銷

  • 排序的時間開銷可用算法執行中的數據比較次數數據移動次數來衡量。
  • 算法運行時間代價的大略估算一般都按平均情況進行估算。對於那些受對象排序碼序列初始排列及對象個數影響較大的,需要按最好情況和最壞情況進行估算。

空間開銷

算法執行時所需的附加存儲。


分類

  • 簡單選擇排序
  • 堆排序

簡單選擇排序

基本思想

首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再從剩余未排序元素中繼續尋找最小(大)元素,然后放到已排序序列的末尾。以此類推,直到所有元素均排序完畢。

C#代碼

    /// <summary>
/// 交換x,y數值
/// </summary>
/// <param name="x">元素1</param>
/// <param name="y">元素2</param>
private static void Swap(ref int x, ref int y)
{
int tmp = x;
x = y;
y = tmp;
}

/// <summary>
/// 簡單選擇排序
/// </summary>
/// <param name="array">待排序數組</param>
/// <returns></returns>
public static int[] SimpleSelectSort(int[] array)
{
if (array.Length > 0)
{
int num = array.Length;//數組大小

int tmp;
for (int i = 0; i < num; i++)//外層遍歷控制
{
tmp = i;
for (int j = i + 1; j < num; j++)//內層遍歷控制
{
if (array[j] < array[tmp])
tmp = j;
}
Swap(ref array[i], ref array[tmp]);
}
return array;
}
else
{
throw new Exception("待排序數組大小不能小於0");
}

}

算法分析

選擇排序的交換操作介於 0 和 ( n − 1 ) 次之間。選擇排序的比較操作為 n ( n − 1 ) / 2 次之間。選擇排序的賦值操作介於 0和 3 ( n − 1 ) 次之間。

比較次數 O ( n 2 ) ,比較次數與關鍵字的初始狀態無關,總的比較次數 N = ( n − 1 ) + ( n − 2 ) + … + 1 = n × ( n − 1 ) / 2 。交換次數 O ( n ) ,最好情況是,已經有序,交換0次;最壞情況是,逆序,交換 n − 1 次。交換次數比冒泡排序較少,由於交換所需CPU時間比比較所需的CPU時間多, n值較小時,選擇排序比冒泡排序快。

原地操作幾乎是選擇排序的唯一優點,當空間復雜度要求較高時,可以考慮選擇排序;實際適用的場合非常罕見。


完整代碼被我放在了Github上,感興趣的可以下下來看一下https://github.com/Finish-Dream/DSAlgorithm

关注微信公众号

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com