摘要:一前言直接插入排序序是一種最簡(jiǎn)單的插入排序。所以,數(shù)據(jù)越接近正序,直接插入排序的算法性能越好。算法穩(wěn)定性直接插入排序的過(guò)程中,不需要改變相等數(shù)值元素的位置,所以它是穩(wěn)定的算法。
一、前言
直接插入排序(Insertion Sort)序是一種最簡(jiǎn)單的插入排序。為簡(jiǎn)化問(wèn)題,我們下面只討論升序排序。
二、算法思想
插入排序:每一趟將一個(gè)待排序的記錄,按照其關(guān)鍵字的大小插入到有序隊(duì)列的合適位置里,直到全部插入完成。
假設(shè)有一組無(wú)序序列 R0, R1, ... , RN-1。
(1) 我們先將這個(gè)序列中下標(biāo)為 0 的元素視為元素個(gè)數(shù)為 1 的有序序列。
(2) 然后,我們要依次把 R1, R2, ... , RN-1 插入到這個(gè)有序序列中。所以,我們需要一個(gè)外部循環(huán),從下標(biāo) 1 掃描到 N-1 。
(3) 接下來(lái)描述插入過(guò)程。假設(shè)這是要將 Ri 插入到前面有序的序列中。由前面所述,我們可知,插入Ri時(shí),前 i-1 個(gè)數(shù)肯定已經(jīng)是有序了。
所以我們需要將Ri 和R0 ~ Ri-1 進(jìn)行比較,確定要插入的合適位置。這就需要一個(gè)內(nèi)部循環(huán),我們一般是從后往前比較,即從下標(biāo) i-1 開(kāi)始向 0 進(jìn)行掃描。
代碼
# -*- coding:utf-8 -*- def insertSort(input_list): if len(input_list) == 0: return [] sorted_list = input_list for i in range(1, len(sorted_list)): temp = sorted_list[i] j = i - 1 while j >=0 and temp < sorted_list[j]: sorted_list[j + 1] = sorted_list[j] j -= 1 sorted_list[j + 1] = temp return sorted_list if __name__ == "__main__": input_list = [6, 4, 8, 9, 2, 3, 1] print("排序前:", input_list) sorted_list = insertSort(input_list) print("排序后:", sorted_list)
三、算法分析
1、直接插入排序的算法性能
2、時(shí)間復(fù)雜度
當(dāng)數(shù)據(jù)正序時(shí),執(zhí)行效率最好,每次插入都不用移動(dòng)前面的元素,時(shí)間復(fù)雜度為O(N)。
當(dāng)數(shù)據(jù)反序時(shí),執(zhí)行效率最差,每次插入都要前面的元素后移,時(shí)間復(fù)雜度為O(N^2)。
所以,數(shù)據(jù)越接近正序,直接插入排序的算法性能越好。
3、空間復(fù)雜度
由直接插入排序算法可知,我們?cè)谂判蜻^(guò)程中,需要一個(gè)臨時(shí)變量存儲(chǔ)要插入的值,所以空間復(fù)雜度為 1 。
4、算法穩(wěn)定性
直接插入排序的過(guò)程中,不需要改變相等數(shù)值元素的位置,所以它是穩(wěn)定的算法。
四、優(yōu)化
因?yàn)樵谝粋€(gè)有序序列中查找一個(gè)插入位置,以保證有序序列的序列不變,所以可以使用二分查找,減少元素比較次數(shù)提高效率。
二分查找是對(duì)于有序數(shù)組而言的,假設(shè)如果數(shù)組是升序排序的。那么,二分查找算法就是不斷對(duì)數(shù)組進(jìn)行對(duì)半分割,每次拿中間元素和目標(biāo)數(shù)字進(jìn)行比較,如果中間元素小于目標(biāo)數(shù)字,則說(shuō)明目標(biāo)數(shù)字應(yīng)該在右側(cè)被分割的數(shù)組中,如果中間元素大于目標(biāo)數(shù)字,則說(shuō)明目標(biāo)數(shù)字應(yīng)該在左側(cè)被分割的數(shù)組中。
代碼
# -*- coding:utf-8 -*- def BinarySearch(input_list, end, value): left = 0 right = end - 1 while left <= right: middle = left + (right - left) // 2 if input_list[middle] >= value: right = middle - 1 else: left = middle + 1 return left if left < end else -1 def BinaryInsertSort(input_list): if len(input_list) == 0: return [] result = input_list for i in range(1, len(input_list)): j = i - 1 temp = result[i] insert_index = BinarySearch(result, i, result[i]) if insert_index != -1: while j >= insert_index: result[j + 1] = result[j] j -= 1 result[j + 1] = temp return result if __name__ == "__main__": input_list = [6, 4, 8, 9, 2, 3, 1] print("排序前:", input_list) sorted_list = insertSort(input_list) print("排序后:", sorted_list)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/43314.html
本篇有7k+字, 系統(tǒng)梳理了js中常見(jiàn)的12種排序算法。除了基本排序算法,文章還包含了希爾排序、堆排序、桶排序等較為復(fù)雜的排序?qū)崿F(xiàn),如果喜歡請(qǐng)點(diǎn)贊支持~謝謝. 原文: http://louiszhai.github.io/20... 導(dǎo)讀 排序算法可以稱得上是我的盲點(diǎn), 曾幾何時(shí)當(dāng)我知道Chrome的Array.prototype.sort使用了快速排序時(shí), 我的內(nèi)心是奔潰的(啥是快排, 我只知道...
希爾排序 在介紹希爾排序之前,先了解一下直接插入排序 文章目錄 希爾排序一、直接插入排序1. 單趟排序2. 直接插入排序 二、希爾排序三、測(cè)試希爾排序和直接插入排序性能 一、直接插入排序 1. 單趟排序 x插入一個(gè)有序區(qū)間 這里end是指向數(shù)組最后一個(gè)元素 2. 直接插入排序 根據(jù)上面的單趟排序啟發(fā) end是數(shù)組的最后一個(gè)元素,end之后的元素都是待排序 一個(gè)關(guān)鍵的判斷點(diǎn),end和...
摘要:之所以把冒泡排序選擇排序插入排序放在一起比較,是因?yàn)樗鼈兊钠骄鶗r(shí)間復(fù)雜度都為。其中,冒泡排序就是原地排序算法。所以冒泡排序是穩(wěn)定的排序算法。選擇排序思路選擇排序算法的實(shí)現(xiàn)思路有點(diǎn)類似插入排序,也分已排序區(qū)間和未排序區(qū)間。 showImg(https://segmentfault.com/img/bVbuvnj?w=900&h=250); 1. 前言 算法為王。 想學(xué)好前端,先練好內(nèi)功,...
摘要:本篇博客我要來(lái)和大家一起聊一聊數(shù)據(jù)結(jié)構(gòu)初階中的最后一篇博客八大經(jīng)典排序算法的總結(jié),其中會(huì)介紹他們的原來(lái),還有復(fù)雜度的分析以及各種優(yōu)化??焖倥判蜻f歸版本快速排序是于年提出的一種二叉樹(shù)結(jié)構(gòu)的交換排序方法。 ...
閱讀 4914·2021-10-13 09:39
閱讀 1971·2019-08-29 11:12
閱讀 1161·2019-08-28 18:16
閱讀 1873·2019-08-26 12:16
閱讀 1260·2019-08-26 12:13
閱讀 3006·2019-08-26 10:59
閱讀 2315·2019-08-23 18:27
閱讀 3004·2019-08-23 18:02