數據結構與算法-排序(二)選擇排序(Selection Sort)


摘要

選擇排序的邏輯是先遍歷比較出序列中最大的,然后把最大的放在最后位置。

遵循這個邏輯,用代碼實現時,做到1.減少比較次數之外,這里引入一個新的指標 - 穩定性,2.保證排序過程中的穩定性也是一個優化處理

代碼邏輯

  1. 從頭遍歷序列,分別和尾部元素比較,記錄最大的元素坐標
  2. 遍歷完成后,和尾部位置交換位置
  3. 忽略尾部已經交換的元素,執行 1 和 2 步驟

實現

依據邏輯來看,最大值是放在尾部,並放置后,下次循環排除這個放置最大值的位置,for 循環從尾部開始最合適。

小循環開始前,需要先創建變量記錄最大值坐標,這里使用的是 0 位置坐標,那么小循環開始時,就可以直接從 1 位置遍歷,這就減少比較次數

	for (int end = array.length-1; end > 0; end--) {
		int maxIndex = 0;
		for (int begin = 1; begin <= end; begin++) {
			if (cmp(maxIndex, begin) < 0) {
				maxIndex = begin;
			}
		}
		swap(maxIndex, end);
	}

進階

開始前,先解釋一下穩定性,穩定性是盡量保持序列中兩個元素在排序前和排序后的相對位置。比如下面偽代碼:


// a1 與 a2 的值相等
a1 = a2 = 3

// 序列中 a1 值的位置在 a2 前面
array = [5, a1, 4, a2, 2]

// 排序之后, a1 值位置在 a2 前面,保持了穩定性
array = [2, a1, a2, 4, 5]

為什么穩定性重要?

序列中需要保證多次排序后數據位置的相對穩定。比如信息表中,以 age 從小到大排序,不希望 age 相等的一組數據中,它的名稱在每一次排序之后都會有不同的順序。

穩定性的優化

這里為了保證排序之后的穩定性,就當出現最大值時,也更新最大值的坐標。

為什么這樣就可以保證穩定性?

首先最大值被交換到尾部之后,下次遍歷比較的時候,就不再比較這個位置,小循環的比較是從頭開始的,如果出現等於最大值時,不更新最大值的位置,排序之后,相等的值,最靠前的值就被放在了最后面,改變了之前序列中相等值的相對位置。

	for (int end = array.length-1; end > 0; end--) {
		int maxIndex = 0;
		for (int begin = 1; begin <= end; begin++) {
			if (cmp(maxIndex, begin) <= 0) { // 保證穩定性
				maxIndex = begin;
			}
		}
		swap(maxIndex, end);
	}

時間和空間復雜度

  • 最好、平均、最壞時間復雜度:O(n^2),n 的 2 次方
  • 空間復雜度:O(1)
  • 屬於穩定排序


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM