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

摘要java

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

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

代碼邏輯

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

實現

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

小循環開始前,須要先建立變量記錄最大值座標,這裏使用的是 0 位置座標,那麼小循環開始時,就能夠直接從 1 位置遍歷,這就減小比較次數class

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)
  • 屬於穩定排序
相關文章
相關標籤/搜索