排序之冒泡排序|Go主題月

排序:按照某種順序排列數據。
例如:一組單詞按照字母順序排序;一組單詞按照單詞長度進行排序。算法

排序的條件:數組

  1. 元素之間能夠按某種規則比較大小;
  2. 明確是否違反順序

假設要求切片數組[10, 1, 5, 3]數據按照升序排列, 以冒泡排序算法做爲排序算法markdown

  1. 冒泡排序屢次遍歷切片數組。它比較相鄰的元素,將不合順序元素交換位置。
  2. 每一輪遍歷都將下一個最大值放到正確的位置上。本質上,每一個元素經過「冒泡」找到本身所屬的位置。
  3. 在按升序的順序排序中,把大的元素不斷的日後移動,這樣每次遍歷結束,大的數據都放到了正確的位置。

第一輪遍歷時,須要遍歷全部的元素,具體見下圖(帶顏色方框的表示正在比較的元素):函數

  1. 首先從0號元素開始遍歷,0號元素即值爲10和1號元素即值爲1進行比較,由於10大於1,因此須要互相交換位置;
  2. 此時,切片數組爲[1, 10, 5, 3],如今遍歷到了1號元素,把1號元素即值爲10和2號元素即值爲5進行比較,由於10大於5,因此須要互相交換位置;
  3. 此時,切片數組爲[1, 5, 10, 3],如今遍歷到了2號元素,把2號元素即值爲10和3號元素即值爲3進行比較,由於10大於3,因此須要互相交換位置;
  4. 此時,切片數組爲[1, 5, 3, 10],第一輪遍歷結束,最大的數字已經位於正確的位置。

冒泡第一輪.png

第二輪遍歷時,由於最後一個元素已經處於正確的位置,因此只須要遍歷0號元素到倒數第二個元素便可,即[1, 5, 3],具體見下圖(帶顏色方框的表示正在比較的元素):post

  1. 此時,切片數組爲[1, 5, 3, 10], 首先從0號元素開始遍歷,0號元素即值爲1和1號元素即值爲5進行比較,由於1小於10,無需交換位置;
  2. 此時,切片數組爲[1, 5, 3, 10],如今遍歷到了1號元素,把1號元素即值爲5和2號元素即值爲3進行比較,由於5大於3,因此須要互相交換位置;
  3. 此時,切片數組爲[1, 3, 5, 10],第二輪遍歷結束,第二大的數值已處於正確的位置。

冒泡第二輪.png

第三輪遍歷時,由於通過前兩輪的排序,目前只需遍歷[1, 3]便可,具體見下圖(帶顏色方框的表示正在比較的元素):優化

  1. 此時,切片數組爲[1, 3, 5, 10],首先從0號元素開始遍歷,0號元素即值爲1和1號元素即值爲3進行比較,由於1小於3,無需交換位置;
  2. 此時,切片數組爲[1, 3, 5, 10], 第三輪遍歷結束。

冒泡第三輪.png

整個切片數值已經按升序排序完畢爲[1, 3, 5, 10]。ui

時間複雜度: O(n²)
從上面的排序過程當中,給n個元素的切片數值冒泡排序須要通過n-1次遍歷,而後每次遍歷的比較次數依次爲n-一、n-二、n-三、...、二、1,因此是1+2+3+...+n-2+n-1的和,即½n²-½n,即O(n²)。spa

使用Golang實現的冒泡排序代碼以下:code

package main

import (
	"fmt"
)

func bubbleSort(numList []int) {
	for needToSortNums := len(numList); needToSortNums > 0; needToSortNums-- {
		// 標記內部循環是否發生了元素交換
		swap := false
		for idx := 0; idx < needToSortNums-1; idx++ {
			if numList[idx] > numList[idx+1] {
				temp := numList[idx]
				numList[idx] = numList[idx+1]
				numList[idx+1] = temp
				swap = true
			}
		}
		// 若是沒有發生元素交換,說明已是正確的順序,函數退出
		if !(swap) {
			return
		}
	}
}

func main() {
	//numList := []int{10, 1, 5, 3}
	numList := []int{10, 1, 5, 3, 2, 7}
	//numList := []int{10, 1, 5, 3}
	fmt.Println(numList)
	// [10 1 5 3]
	bubbleSort(numList)
	fmt.Println(numList)
	// [1 3 5 10]
}
複製代碼

選擇排序爲在冒泡排序基礎上進行優化後的一種排序算法。orm

相關文章
相關標籤/搜索