穩定性:若是a本來在b前面且a=b,排序以後a仍然在b前面,則穩定;若是排序以後a可能會在b後,則不穩定。html
經過比較來決定元素間的相對次序,時間複雜度不能突破O(nlogn)。算法
一次比較兩個元素,若是順序不對則交換過來。shell
時間複雜度:O(n^2),優化後最好時間複雜度可爲O(n)。
空間複雜度:O(1)。
穩定性:穩定。數組
示例代碼:數據結構
//普通 function srotfunction($a){ $count = count($a); for($i=$count-1; $i>0; $i--){ for($j=0;$j<$i;$j++){ if($a[$j] > $a[$j+1]){ $tmp = $a[$j]; $a[$j] = $a[$j+1]; $a[$j+1] = $tmp; } } } return $a; } //優化後,用 didswap 標記是否有交換動做。若是自己有序,則執行一次。 function srotfunction($a){ boolean $didswap; $count = count($a); for($i=$count-1; $i>0; $i--){ $didswap = false; for($j=0;$j<$i;$j++){ if($a[$j] > $a[$j+1]){ $tmp = $a[$j]; $a[$j] = $a[$j+1]; $a[$j+1] = $tmp; $didswap = true; } } if($didswap == false){ break; } } return $a; }
經過基準元素,分爲兩組子串,繼續對字段分組,以達到整個序列有序。基準元素通常選擇第一個元素或最後一個元素。函數
時間複雜度:O(nlogn)。
空間複雜度:O(nlogn)。
穩定性:不穩定。優化
代碼示例:ui
function partition(&$a, $low, $high){ $privotKey = $a[$low]; while($low<$high){ //大於的部分 while($low<$high && $a[$high]>$privotKey){ --$high; } swap($a, $low, $high); while($low<$high && $a[$low]<$privotKey){ ++$low; } swap($a, $low, $high); } return $low; } function quicksort(&$a, $low, $high){ if($low < $high){ $privotloc = partition($a, $low, $high); quicksort($a, $low, $privotloc-1); quicksort($a, $privotloc+1, $high); } } $b = quicksort($a, 0, count($a)-1);
構建有序序列,對未排序單元,在已排序序列中從後向前掃描,找到相應位置並插入。spa
時間複雜度:O(n^2),已有序只比較一次,複雜度爲O(n)。
空間複雜度:O(1)。
穩定性:穩定。code
代碼示例:
function srotfunction($a){ $len = count($a); for($i=1; $i<$len; $i++){ $current = $a[$i]; $preIndex = $i - 1; while($preIndex >=0 && $a[$preIndex] > $current){ $a[$preIndex+1] = $a[$preIndex]; $preIndex--; } $a[$preIndex + 1] = $current; } return $a; }
把數據按下標增量分爲多個分組,每組內用插入排序。希爾增量序列{n/2, (n/2)/2, ..., 1}。
時間複雜度:O(n^2)。一些優化的增量序列能夠爲O(n^3/2)。已經有序的爲O(n)。
空間複雜度:O(1)。
穩定性:不穩定。
代碼示例:
function srotfunction($a){ $len = count($a); $gap = intval($len / 2); for(;$gap>0;$gap=intval($gap/2)){ for($i=$gap;$i<$len;$i++){ $j = $i; $tmp = $a[$i]; if($a[$j] < $a[$j-$gap]){ while($j-$gap>=0 && $a[$j-$gap]>$tmp){ $a[$j] = $a[$j-$gap]; $j-=$gap; } $a[$j] = $tmp; } } } return $a; }
從未排序字段中找到最小(最大)的元素,放入已排序字段中。
時間複雜度:O(n^2)。
空間複雜度:O(1)。
代碼示例:
function srotfunction($a){ $len = count($a); for($i=0; $i<$len-1; $i++){ $min = $i; for($j=$i+1; $j<$len; $j++){ if( $a[$min] > $a[$j]){ $min = $j; } } if($min != $i){ $tmp = $a[$min]; $a[$min] = $a[$i]; $a[$i] = $tmp; } } return $a; }
利用堆的數據結構,反覆調整結構以使其知足堆定義。
堆:徹底二叉樹,每一個節點的值都大於或等於其左右孩子節點的值(大頂堆),同理小頂堆。
時間複雜度:O(nlogn)。
空間複雜度:O(1)。
基本思路:
分治法,將已有有序子序列合併得到有序序列。二路歸併排序、多路歸併排序。
時間複雜度:O(nlogn)。
空間複雜度:O(n)。
穩定性:穩定。
代碼示例:
function mergeSort(arr) { // 採用自上而下的遞歸方法 var len = arr.length; if (len < 2) { return arr; } var middle = Math.floor(len / 2), left = arr.slice(0, middle), right = arr.slice(middle); return merge(mergeSort(left), mergeSort(right)); } function merge(left, right) { var result = []; while (left.length>0 && right.length>0) { if (left[0] <= right[0]) { result.push(left.shift()); } else { result.push(right.shift()); } } while (left.length) result.push(left.shift()); while (right.length) result.push(right.shift()); return result; }
不經過比較來決定次序,能夠以線性時間運行。
將輸入的數據值轉化爲鍵,存儲在額外的數組空間中。要求輸入的數據必須是有肯定範圍的整數,k不是很大且序列比較集中時。
時間複雜度:O(n+k) //輸入元素是n個0~k之間的整數
空間複雜度:O(n+k)
穩定性:穩定
算法描述:
利用函數的映射關係,計數排序的升級版。
算法描述:
先按低位優先級排序、收集,再按高位優先級排序、收集,以此類推。