排序 3 折半插入排序

2021-08-09 00:23:22 字數 2423 閱讀 8612

參考:

排序 0 - 前言

對插入排序演算法的改進,針對已排序序列,利用二分法進行資料查詢,將待排序資料插入到已經排好序的有序資料中,從而得到乙個新的、個數加一的有序資料。

設待排序序列大小為n,共遍歷n-1次,i表示當前遍歷的次數,也表示已排序序列的終止位置和待排序序列的起始位置。設定已排序序列開始和末尾下標為lowhigh,其中中間位置資料的下標為m = (low+high)/2。將待排序資料和中間位置資料進行比較,如果中間位置資料小於等於(或者大於等於)待排序資料,則設定low = m+1;否則high = m-1,然後繼續計算中間下標m,進行比較,直到滿足條件low > high為止,將待排序資料插入到hight+1的位置

# -*- coding: utf-8 -*-

"""二分插入排序,又稱折半插入排序

"""import random

def create_data(leng, min, max):

"""建立待排序序列

:param leng: 序列長度

:param min: 最小值

:param max: 最大值

:return: 列表

"""li = range(min, max)

return random.sample(li, leng)

def binary_insert_sort(li, reverse=false):

"""二分插入排序實現

:param li: 待排序列表

:param reverse: 是否從大到小排序,預設為false

:return: 已排序列表

"""for i in xrange(1, len(li)):

low = 0

high = i - 1

while low <= high:

m = (low + high) / 2

if li[m] <= li[i]:

if reverse:

high = m - 1

else:

low = m + 1

else:

if reverse:

low = m + 1

else:

high = m - 1

li.insert(high + 1, li[i])

del li[i + 1]

return li

if __name__ == '__main__':

da = create_data(10, 30, 60)

print da

binary_insert_sort(da, true)

print da

折半插入排序是穩定排序演算法

折半插入排序是對插入排序演算法的改進,重點變化在於待排序資料的比較過程。

但是,在實際程式設計中,同樣有可能使折半插入排序成為不穩定的排序演算法,下面介紹不穩定的排序演算法過程

假設有如下待排序序列:(3,0),(2,1),(3,2),實現從小到大的排序

得到結果:(2,1),(3,0),(3,2)

第一次比較,(2,1)小於(3,2),所以low = m+1 = 1, m = (low + high) / 2 = 1

第二次比較,(3,0)大於等於(3,2),所以high = m-1 = 0,所以low > high,將(3,2)插入到high+1 = 1的位置上

得到結果:(2,1),(3,2),(3,0),是不穩定的排序結果

所以,在比較時,當中間資料 大於等於(或者小於等於)待排序資料時,選擇右邊已排序序列繼續操作,才能保證是穩定的

折半插入排序改變了插入排序演算法的比較次數,未改變其待排序資料移動次數

最好情況下,插入的位置,剛好是二分位置,時間複雜度為o(nlogn)

最壞情況下,時間複雜度為o(n^2)

平均時間複雜度為o(n^2)

空間複雜度為o(1)

排序演算法之插入排序2 折半插入排序

我們都知道插入法是在要插入的元素前面都已序的情況下進行比較 插入,直接插入法每個元素都有可能會經歷多次交換才能找到它本應該待的位置。比如第100個元素,假如它應該待的位置為2,如果用直接插入法的話,就要比較99次,搬移98次。然而它前面的99個元素是已序的,顯然有優化的空間,面對已序的序列我們最先想...

插入排序之 二分(折半)插入排序(c c )

相比較直接插入排序,二分插入的優勢在於 對待排序數所應該插入的位置的計算是通過二分法來尋找的,這種二分查詢的時間複雜度為o logn 而直接插入是依次尋找位置的,時間複雜度可看作o n 故二分插入排序是一種優化過的插入排序。完整二分插入公升序 如下 includevoid insertsort in...

Java排序之插入排序 二分 折半插入排序 4

原理 二分插入排序就是插入排序的乙個變種,就是尋找插入排序的位置是採用二分查詢的方式查詢的,都是把整個陣列分為乙個有序的陣列,然後乙個無序的陣列,開始的有序陣列長度為1,然後把無序陣列遍歷,挨個插入有序陣列中,直到所有的數都變成有序的。時間複雜度 其時間複雜度跟插入排序是一樣的 都是o n 2 實現...