演算法小專欄:選擇排序

QiShare發表於2019-03-25

級別: ★☆☆☆☆
標籤:「演算法」「選擇排序」「Selection Sort」
作者: MrLiuQ
審校: QiShare團隊


本篇將重點介紹選擇排序,在講解選擇排序之前,我們先複習一下陣列和連結串列等知識。

一、陣列 or 連結串列?

陣列和連結串列作為常用的儲存資料結構,有各自的優勢與劣勢。

  • 陣列的優勢在於查詢速度快。
  • 連結串列的優勢在於插入刪除速度快。

下面是兩者的時間複雜度:

/ 陣列 連結串列
讀取 O(1) O(n)
插入 O(n) O(1)
刪除 O(n) O(1)

為什麼呢? 這與陣列與連結串列的儲存方式有關。

陣列是順序儲存,而連結串列是鏈式儲存

  • 順序儲存:所儲存的記憶體區域是連續的。
  • 鏈式儲存:所儲存的記憶體區域是非連續的。

舉個例子:圖解一下

演算法小專欄:選擇排序

因此,當我們所儲存的資料經常查詢,則選擇陣列好一些。 如果我們的資料經常被操作,並且資料長度經常發生變化,則選擇連結串列好一些。

關於陣列的記憶體儲存還有幾個小知識點:

  1. 對於不可變陣列來說,每一次重新賦值都是一次記憶體整體遷移,相當於開闢了一塊新記憶體儲存資料。

  2. 對於可變陣列來說,系統會預留記憶體位置,當可變陣列的大小超過這個預留記憶體大小時,會做整體資料遷移,會遷移到一塊更大的預留記憶體位置。

二、選擇排序

我們先來看一下選擇排序的演算法流程:

演算法小專欄:選擇排序

解釋:
1.每一次迴圈 找到 未排序佇列中的最小值的index。(n次)
2.再與前置位交換,未排序佇列元素數-1
3.重複n次,得出最終排序佇列, 故時間複雜度 = O(n2)

下面是基於python的實現程式碼:

  • 每一次迴圈 找到 未排序佇列中的最小值的index。(n次)
def findSmallest(arr):
    smallest = arr[0]
    smallest_index = 0
    for i in range(1, len(arr)):
        if arr[i] < smallest:
            smallest = arr[i]
            smallest_index = i
    return smallest_index
複製程式碼
  • 再與前置位交換,未排序佇列元素數-1。(也可以加入新陣列)
def selectionSort(arr):
    newArr = []
    for i in range(len(arr)):
        smallest = findSmallest(arr)
        newArr.append(arr.pop(smallest))
    return newArr
複製程式碼
  • 完整示例程式碼:
def findSmallest(arr):
    smallest = arr[0]
    smallest_index = 0
    for i in range(1, len(arr)):
        if arr[i] < smallest:
            smallest = arr[i]
            smallest_index = i
    return smallest_index

def selectionSort(arr):
    newArr = []
    for i in range(len(arr)):
        smallest = findSmallest(arr)
        newArr.append(arr.pop(smallest))
    return newArr

print selectionSort([5, 3, 2, 10, 6, 4, 7])
複製程式碼

工程原始碼:QiAlgorithms的2-2demo


小編微信:可加並拉入《QiShare技術交流群》,二維碼連結

關注我們的途徑有:
QiShare(簡書)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公眾號)

推薦文章:
iOS Runloop(一)
iOS 常用除錯方法:LLDB命令
iOS 常用除錯方法:斷點
iOS 常用除錯方法:靜態分析
iOS訊息轉發
iOS 自定義拖拽式控制元件:QiDragView
iOS 自定義卡片式控制元件:QiCardView
iOS Wireshark抓包
iOS Charles抓包
奇舞週刊

相關文章