插值排序或稱為直方圖排序是一種使用插值公式分散資料分而治之的排序演演算法。插值排序也是桶排序演演算法的一種變型。 插值排序遞迴演算法 插值排序也是一種桶排序，排序演演算法與桶排序相同，插值公式是把被排序的數字化為介於零到壹的數值，再乘以桶子的數量，得出被排序數字對應的桶子號碼，以此號碼分桶來實現桶排序。一個通用的插值公式是： 插值 取整數 設算數 最小數 最大數 最小數 桶子數量 1 插值排序遞迴演算法流程 尋訪序列，找出最大值與最小值，如果相等排序完成。 設定一個定量的陣列當作空桶子。 尋訪序列，把專案一個一個放到插值對應的桶子去。 對每個不是空的桶子再次進行桶排序。 從不是空的桶子裡把專案再放回原來的序列中。 插值排序遞迴演算法實作 JavaScript code ArrayprototypebucketSort function edit date20190831 Taiwan var start 0 var size thislength var min this 0 var max this 0 for var i 1 i size iif this i minmin this i else if this i maxmax this i if min maxvar bucket new Array size for var i 0 i size ibucket i new Array var interpolation 0 for var i 0 i size iinterpolation Mathfloor this i min max min size 1 bucket interpolationpush this i for var i 0 i size iif bucket ilength 1bucket ibucketSort 遞迴 for var j 0 j bucket ilength jthis start bucket ij 插值排序演演算法 插值排序遞迴方式運用一個記錄桶子長度的陣列對應原數列，透過操作維護長度陣列可以避免遞迴演演算法因記憶體堆疊而使空間複雜度變成 O n 2，藉由長度陣列的分段記錄可以使用次函式動態的宣告與刪除陣列的記憶體空間，使得遞迴程式得以控制所需空間複雜度在 O 3n，包含一個動態分配記憶體的二維陣列與一個記錄長度的陣列。但是平均時間複雜度仍可維持為 O n k 的高效排序方法。 動態分配記憶體的陣列也可以由連結串列、堆疊、佇列、關聯陣列、樹狀結構等實作，例如 Javascript 的陣列物件即適用。資料結構的不同關係著資料存取的速度進而影響到排序所需的時間。當被排序陣列內的數值是均勻分散近似等差級數時，插值排序的線性時間為 O n。 插值排序流程 設定一個桶子長度陣列記錄未完成排序桶子的長度。初始化放入 push 原始陣列的長度。 主排序：如果桶子長度陣列清空排序完成。如果未清空執行 分桶函式。 分桶函式：從桶子長度陣列末端取出 pop 一個桶子長度執行分桶。如果最大值等於最小值該序列排序完成停止分桶。 設定一個二維陣列當作空桶子。依照插值分桶。 分桶後從不是空的桶子裡把專案逐一放回原始陣列。 並在桶子長度陣列加入 push 桶子的長度。 返回 主排序。 插值排序實作 JavaScript code ArrayprototypeinterpolationSort function edit date20190731 var bucketSize new Array var end thislength bucketSize 0 end while bucketSizelength 0DivideToBucket this function DivideToBucket needSortArrayvar size bucketSizepop var start end size var minimum needSortArray start var maximum needSortArray start for i start 1 i end iif needSortArray i minimumminimum needSortArray i else if needSortArray i maximummaximum needSortArray i if minimum maximumend end size else var interpolation 0 var bucket new Array size for i 0 i size ibucket i new Array for i start i end iinterpolation Mathfloor needSortArray i minimum maximum minimum size 1 bucket interpolationpush needSortArray i for i 0 i size iif bucket ilength 0for j 0 j bucket ilength jneedSortArray start bucket ij bucketSizepush bucket ilength 變種 插值標簽排序 插值標簽排序 Interpolation Tag Sort 是插值排序 Interpolation Sort 的變型，應用桶排序分而治之的方法，以數學插值公式將陣列資料以陣列方式分散到有限數量的桶子裡，桶子再遞迴原處理程序直到完成排序。 插值標簽排序是插值排序的遞迴排序方法，為避免遞迴造成堆疊溢位使得記憶體崩潰，而利用一個布林資料型別的標簽陣列操做遞迴次函式以釋放記憶體。所需額外記憶體的空間複雜度約等於 2nn bits，包含一個動態分配記憶體的二維陣列與一個布林資料型別的標簽陣列。除此之外關聯陣列、連結串列、堆疊、佇列、樹狀結構等皆可實作成桶排序的桶子。誠如 Javascript 的陣列物件即適用於此排序方法，資料結構的不同關係著資料存取的速度進而影響到排序所需的時間。當要被排序的陣列內的數值是均勻分佈的時候使用線性時間 Theta n 。桶排序演演算法並不是比較排序不受 O n log n 下限的限制。插值標簽排序是桶排序的變型平均執行複雜度同為 O n k。 插值標簽排序演演算法 設定一個與原始陣列等量的標簽陣列，並初始化為假值。 主排序 判斷原始陣列所有桶子是否都已排序完成，未完成執行 分桶函式。 分桶函式 找出桶子內最大最小值，如果最大值等於最小值排序完成停止分桶。 設定一個二維陣列當作空桶子。依照插值分桶。 分桶後從不是空的桶子裡把專案逐一放回原始陣列。並在標簽陣列將桶子的起始位置標記為真值。 返回 主排序。 插值標簽排序實作 JavaScript code ArrayprototypeInterpolaionTagSort function Whale Chen 同意：「維基百科：CC BYSA 30 協議文字」編輯日：20190804 var start 1 var end this length var Tag new Array end Algorithm step1 for i 0 i end i Tag i false Tag 0 true while end 0 Algorithm step2 while Tag start false DivideToBucket this function DivideToBucket Avar minimum A start var maximum A start for i start 1 i end i if A i minimumminimum A i else if A i maximum maximum A i if minimum maximumend startAlgorithm step3 else var interpolation 0 var size end start var Bucket new Array sizeAlgorithm step4 for i 0 i size i Bucket i new Array for i start i end i interpolation Math floor A i minimum maximum minimum size 1 Bucket interpolationpush A i for i 0 i size i if Bucket ilength 0 Algorithm step5 Tag start true for j 0 j Bucket ilength j A start Bucket ij Algorithm step6 原地插值排序 原地插值排序是插值排序的原地演算法（inplace algorithm）。原地插值排序透過插值計算交換元素完成排序；但是要排序的陣列必需是算術級數，例如連續整數。原地插值排序對不重複的等差數列排序，序列從頭開始計算元素的插值，插值指向元素排序好的位置，兩者相互調換位置，遞增而行至序列結尾排序完成。計算時間複雜度為：O n，最壞空間複雜度：O 1。 原地插值排序實作 JavaScript code Arrayprototypein_placeInterpolationSort function Date20191115 Arithmetic progression only var n thislength var min this 0 var max this 0 for var i 1 i n iif this i minmin this i else if this i maxmax this i var position n var temp 0 for var i 0 i n iposition Mathfloor this i min max min n 1 while i positiontemp this position this position this i this i temp position Mathfloor this i min max min n 1 類似排序方法 直方圖排序 Histogram sort 直方圖排序不使用陣列物件 類似 ArrayList 作桶子，而是使用一維的輔助陣列分段當作桶子。首先用插值公式敲擊桶子計算每個桶子的敲擊數量，並使用另一個陣列記錄桶子的資料數量，再把每個敲擊的數量累加，得到桶子在輔助陣列的起始位置。然後再次用插值公式把資料逐一放進桶子裡，當資料放置完畢，將輔助陣列的資料複製回原陣列，然後利用桶子的數量記錄，對每個桶子再次使用直方圖排序直到排序完成。 ArrayprototypehistogramSort function Edit date20191107 Taiwan var end thislength var sortedArray new Array end var interpolation new Array end var hitCount new Array end var divideSize new Array divideSize 0 end while divideSizelength 0distribute this Repeat the distribute function instead of recursion function distribute Avar size divideSizepop var start end size var min A start var max A start for var i start 1 i end iif A i minmin A i else if A i maxmax A i if min maxend end size else for var i start i end ihitCount i 0 for var i start i end iinterpolation i start Mathfloor A i min max min size 1 hitCount interpolation i for var i start i end iif hitCount i 0divideSizepush hitCount i hitCount end1 end hitCount end1 for var i end1 i start ihitCount i1 hitCount i hitCount i1 for var i start i end isortedArray hitCount interpolation i A i hitCount interpolation i for var i start i end iA i sortedArray i 相鄰圖排序 ProxmapSort 相鄰圖排序也是使用一維的輔助陣列當作桶子，桶子分段方式與直方圖排序相同，不同的是用插值公式將資料分配到輔助陣列的桶子時，隨後使用插入排序插入資料讓資料有序，當分配資料完成時排序完成，將輔助陣列的資料複製回原陣列。 ArrayprototypeProxmapSort function Edit date20191111 Taiwan var start 0 var end thislength var size end start var sortedArray new Array end var interpolation new Array end var hitCount new Array end for var i start i end ihitCount i 0 var min this start var max this start for var i start1 i end iif this i minmin this i else if this i maxmax this i for var i start i end iinterpolation i Mathfloor this i min max min size 1 hitCount interpolation i hitCount end1 end hitCount end1 for var i end1 i start ihitCount i1 hitCount i hitCount i1 insertion sort this i to correct position var insertIndex 0 var insertStart 0 for var i start i end iinsertIndex hitCount interpolation i insertStart insertIndex while sortedArray insertIndex nullinsertIndex while insertIndex insertStart this i sortedArray insertIndex1sortedArray insertIndex sortedArray insertIndex1 insertIndex sortedArray insertIndex this i for var i start i end ithis i sortedArray i 閃電排序 FlashSort 閃電排序不使用一維輔助陣列，而是將原始陣列視為分段的桶子，利用交換的方式將資料放入桶子。首先用插值公式計算各個點該有的資料數量，再把該數量累加得到每個點的最終位置。然後在用插值公式把資料與對應的點交換，當所有資料交換完畢，資料已經都在桶子裡，桶子是有序的所以陣列接近排序完成，當資料接近有序時使用插入排序會很快，最後使用插入排序將整個陣列完成排序。 ArrayprototypeFlashSort function Edit date20191124 Taiwan var start 0 var end thislength var size end start var hitCount new Array end var min this start var max this start for var i start 1 i end iif this i minmin this i else if this i maxmax this i for var i start i end ihitCount i 0 var interpolation 0 for var i start i end iinterpolation Mathfloor this i min max min size 1 hitCount interpolation hitCount 0 hitCount 0 1 for var i 1 i end ihitCount i hitCount i hitCount i1 var temp 0 var tag new Array end for var i start i end itag i false for var i start i end iwhile tag i falseinterpolation Mathfloor this i min max min size 1 tag hitCount interpolation true temp this hitCount interpolation this hitCount interpolation this i this i temp hitCount interpolation insertionSort var key 0 var j 0 for var i 1 i end ikey this i j i 1 while j 0 key this jthis j1 this j j this j1 key 插值排序混合其他排序方法 插值排序是一種桶排序，桶排序可以混合其他排序方法完成排序，若是由桶排序與插入排序混合，亦是相當高效的排序方法。但是當數列出現一個乖離很大的數值，例如數列最大值大於次大值的 N 倍時，數列分桶處理後分佈情形是除了最大值以外其餘元素都落入同一個桶子，緊接著第二個排序方法使用插入排序，可能會使得執行複雜度陷入 O n2，如此便失去了使用桶排序分而治之的意義與執行效能。 插值排序是使用桶排序遞迴的方式，執行遞迴以後仍然使用桶排序分散數列，這樣可以避免上述情形。如欲使得遞迴的插值排序執行複雜度陷入 O n2，則必需在整個數列呈現階乘放大的情況，相對上數列要出現這種特殊分佈情形的機率很少。 插值排序混合插入排序流程 尋訪序列，找出最大值與最小值，如果相等排序完成。 設定一個定量的陣列當作空桶子。 尋訪序列，並且把專案放到對應的桶子去。 在桶子內把該專案直接進行插入排序。 從不是空的桶子裡把專案再放回原來的序列中。 插值排序混合插入排序實作 JavaScript code ArrayprototypeinterpolationInsertSort function Edit date20190902 Taiwan var start 0 var size thislength var min this 0 var max this 0 for var i 1 i size iif this i minmin this i else if this i maxmax this i if min maxvar bucket new Array size for var i 0 i size ibucket i new Array var buckets size 1 var range max min var interpolation 0 var insetIndex 0 var k 0 for var i 0 i size iinterpolation Mathfloor this i min range buckets bucket interpolationpush this i insetIndex 0 專案放到對應桶子後，直接執行插入排序。 while this i bucket interpolationinsetIndexinsetIndex k bucket interpolationlength1 while k insetIndexbucket interpolationk bucket interpolationk1 k bucket interpolationinsetIndex this i for var i 0 i size ifor var j 0 j bucket ilength jthis start bucket ij 參考 額外參考 1 interpolationSorthtml 2 histogramSorthtml 3 The FlashSort Algorithm 4 Mathematical Analysis of Algorithms 5 httpwwwdrdobbscomdatabasetheflashsort1algorithm184410496 額外連結 Interpolation Sort AlgorithmWhale Chen 20120916 桶排序遞迴方式演演算法 Bucket Sort recursive method 插值標簽排序演演算法 Interpolation Tag Sort Algorithm interpolation sort Pascal version available w3schools JavaScript Array Sort 測試平臺 Category 排序演算法