資料結構之內部排序--直接插入排序
概要
-IDE:Pycharm
-Python版本:python3.x
-演算法分類:內部排序->插入類排序->直接插入排序
演算法思想
直接插入排序是一種最基本的插入排序方法,其基本操作是將第$i$個記錄插到前面$i-1$個記錄中。然後將大於自身的記錄從後往前依次向後移一位.
例如:將第$i$個記錄的關鍵字$K_i$順次與前面的$K_{i-1},K_{i-2},...,K_1$進行比較,將所有大於$K_i$的記錄依次向後移動一位。直到遇到小於$K_i$的記錄,假設此記錄為$K_j(j<i)$,依次向後移了之後位置$i$必定為空。此時將$K_i$,放入$K_j(j<i)$的位置。
為提高效率,輔設一監視哨(可以自己設定建議使用r[0]),監視哨作用有兩個,一是備份待插入記錄,二是防止越界。
演算法分析
從空間角度來看,它只需要一個輔助空間。從時間角度來看,耗費時間主要是比較和移動元素。
對於一趟迴圈來說:
-最好情況順序:$r[i].key>r[i-1].key$,while迴圈只執行一次,且不移動記錄。
-最壞情況逆序:$r[i].key<r[1].key$,while迴圈中關鍵字比較次數和一從次數為$i-1$
對於整個迴圈來說:
-最好情況下比較總次數達到了$n-1$次,移動記錄的次數也達到最小值$2(n-1)$次。
-最壞情況下比較總次數到到了$(n+2)(n-1)/2$次,移動記錄的次數也達到了$(n+4)(n-1)/2$次。
演算法要點
-使用使用監視哨r[0]臨時儲存待插入記錄。
-從後往前尋找插入位置。
-查詢與移動同一迴圈完成。
穩定性與時間複雜度
排序演算法 | 穩定性 | 時間複雜度 | 最好情況 | 最壞情況 | 空間複雜度 |
---|---|---|---|---|---|
直接插入 | 穩定 | $O(n^2)$ | $O(n)$ | $O(n^2)$ | $O(1)$ |
Python程式碼清單
# !/usr/bin/python3 # _*_ coding:utf-8 _*_ # 直接插入排序 import sys # 匯入sys,使用argv接收外部引數。 import time # 匯入time 用time() 進行記時。 import random # 匯入隨機數包生存隨機數 def SSS(number,maxNumber): # 演算法,number是傳入生成的個數,maxNumber代表生成的最大數 # 生成隨機數 timeStart = time.time() listA = [0] # 0位 監視哨 for i in range(number): listA.append(random.randint(0, maxNumber)) # 新增生成的值。 timeEnd = time.time() timeIs = timeEnd-timeStart print('生成%d個數的時間是%f' % (number, timeIs)) #print(listA[1:]) #################################################### # 進行排序 timeStart = time.time() for aim in range(2, number+1): # 迴圈遍歷列表,因為設定了監視哨所以生成的位數多了一位,這裡遍歷自然+1 index = aim # 用來做索引 listA[0] = listA[aim] # 設定監視哨的值。 while(listA[index-1] > listA[0]): # 迴圈查詢監視哨之前的那個值不大於監視哨。 listA[index] = listA[index-1] # 向後挪一位。 index = index-1 # 索引向前一位。 listA[index] = listA[0] #符合條件,進行插入。 timeEnd = time.time() timeIs = timeEnd-timeStart print('排序%d個數的時間是%f' % (number, timeIs)) print(listA[1:]) if __name__ == '__main__': helpInfo = ''' This program is for Straight Select Sorting. How to use it! Follow the example! python Straight_Select_Sorting.py 10 100 The 10 representative will generate ten numbers. 100 representative the max-number you make. ''' command = sys.argv[0:] # 從鍵盤獲取輸入資訊。 lenght = len(command) # 計算資訊長度 if lenght != 3 or 'help' in command: # 第一判斷,對長度是否合法與是否有幫助文字進行判斷。 print(helpInfo) else: try: number = int(command[1]) # 第二次判斷,對輸入資料進行int轉化,即判斷是否為int maxNumber = int(command[2]) except ValueError: print(helpInfo) sys.exit(1) # 若不是int,則退出程式 SSS(number, maxNumber) # 呼叫方法,生成序列並排序。
總結
學時容易寫時難。學得時候我們學得是理論,而寫的時候則完全不一樣。你需要知道每一步是如何變化的。把一個整體要全部分解為原子,這需要不斷的練習。
有什麼問題請聯絡我
QQ:3116316431 (請附上資訊)
E-mail:[email protected]