一、冒泡排序
排序規則:比較相鄰元素,符合比較條件,交換位置較大的往后排,反復比較交換,直到所有數據都符合排序條件,得出排序效果,結束排序。
穩定性:穩定
排序動態示意:

代碼實現:
var arr = [3,4,1,2,21,5,15,6,63];
function BubbleSort(ary){
for(var i = 0; i < ary.length - 1; i++){
for(var j = i + 1; j < ary.length; j++){
var current = ary[i];
if(current > ary[j]){
var tmp = ary[j];
ary[j] = current;
ary[i] = tmp;
}
}
}
return ary;
}
BubbleSort(arr); // [1, 2, 3, 4, 5, 6, 15, 21, 63]
二、選擇排序
排序規則:通過比較,選出最小的數放在第一位,然后在其余所有的數中選出最小的數排在第二位,以此類推,直到排序結束。
穩定性:不穩定
排序動態示意:

代碼實現:
var arr = [3,4,1,2,21,5,15,6,63];
function SelectSort(ary){
for(var i = 0; i < ary.length - 1; i++){
for(var j = i + 1; j < ary.length; j++){
if(ary[i] > ary[j]){
var tmp = ary[i];
ary[i] = ary[j];
ary[j] = tmp;
}
}
}
return ary;
}
SelectSort(arr); // [1, 2, 3, 4, 5, 6, 15, 21, 63]
三、插入排序
排序規則:插入排序得比喻成斗地主,手里摸牌之后都是按照從小到大的順序。每摸到一張牌就把他們插入到合適的位置,使得他們比后面小,比前面大或者相等。
穩定性:穩定
排序動態示意:

代碼實現:
var arr = [3,4,1,2,21,5,15,6,63];
function InsertSort(ary){
var temp;
for (var i = 1; i < ary.length; i++) {
for (var j = i-1; j >=0; j--) {
if (ary[j+1] < ary[j]) {
temp = ary[j+1];
ary[j+1] = ary[j];
ary[j] = temp;
} else if (ary[j+1] >= ary[j]) {
break;
}
}
}
return ary;
}
InsertSort(arr); // [1, 2, 3, 4, 5, 6, 15, 21, 63]
四、快速排序
排序規則:從數組中找一個基准值,通過這個值挨個和數組中的值進行比較,大的放一邊,小的放一邊,然后進行合並后,在進行比較,反復直至結束。
穩定性:不穩定
排序動態示意:

代碼實現:
var arr = [3,4,1,2,21,5,15,6,63];
var quickSort = function(ary) {
if (ary.length <= 1) {
return ary;
}
var pivotIndex = Math.floor(ary.length / 2);
var pivot = ary.splice(pivotIndex, 1)[0];
var left = [];
var right = [];
for (var i = 0; i < ary.length; i++) {
if (ary[i] < pivot) {
left.push(ary[i]);
} else {
right.push(ary[i]);
}
}
return quickSort(left).concat([pivot], quickSort(right));
};
quickSort(arr); // [1, 2, 3, 4, 5, 6, 15, 21, 63]
五、堆排序
排序規則:堆是一棵順序存儲的二叉樹,堆分為最大堆和最小堆,最大堆父節點都大於子節點, 最小堆父節點都小於子節點,左子節點: 2*i +1 (i: 父節點index),右子節點: 2*i+2,從最后一個非葉子節點開始將堆進行小頂堆排序,每次拿出根節點,並和最后一個節點進行交換,重新進行堆的建立。
穩定性:不穩定
排序動態示意:

代碼實現:
var arr = [3,4,1,2,21,5,15,6,63];
function HeapSort(ary) {
// 實現最大堆
// start: 父節點, end: 循環深度
function maxHeap(ary, start, end) {
let parent = start, // 父節點
son = parent*2 + 1, // 左子節點
temp = null;
// 規定循序最大深度
while(son<=end) {
// 如果存在右子節點, 並且判斷右節點是否大於左節點
if(son+1<=end && ary[son] < ary[son+1]) son++;
if(ary[son] > ary[parent]) {
temp = ary[son];
ary[son] = ary[parent];
ary[parent] = temp;
parent = son;
son = parent*2 +1;
}else {
return;
}
}
}
// 構建最大堆 ary.length/2-1: 表示最后一個父節點
for(let i = ary.length/2-1; i>=0; i--) {
maxHeap(ary, i, ary.length-1);
}
// 排序
for(let i = ary.length-1; i>0; i--) {
let temp = ary[0];
ary[0] = ary[i];
ary[i]= temp;
// 剔除最后一個元素,並復原最大堆
maxHeap(ary, 0, i-1);
}
return ary;
}
HeapSort(arr); // [1, 2, 3, 4, 5, 6, 15, 21, 63]
六、遞並排序
排序規則:將長的數組分解為短的數組,一直分到最后,單個單個數組比較,我們就認為,只有一個元素的數組是有序的。然后再逐個的合並。
穩定性:穩定
排序動態示意:

代碼實現:
var arr = [3,4,1,2,21,5,15,6,63];
function MergeSort(ary) { //采用自上而下的遞歸方法
var len = ary.length;
if(len < 2) {
return ary;
}
var middle = Math.floor(len / 2),
left = ary.slice(0, middle),
right = ary.slice(middle);
return merge(mergeSort(left), mergeSort(right));
}
function merge(left, right)
{
var result = [];
while (left.length && right.length) {
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;
}
MergeSort(arr); // [1, 2, 3, 4, 5, 6, 15, 21, 63]
七、希爾排序
排序規則:希爾排序是插入排序的一種更高效率的實現。它與插入排序的不同之處在於,它會優先比較距離較遠的元素。希爾排序的核心在於間隔序列的設定。既可以提前設定好間隔序列,也可以動態的定義間隔序列。
穩定性:不穩定
排序動態示意:

代碼實現:
var arr = [3,4,1,2,21,5,15,6,63];
function ShellSort(ary) {
var len = ary.length,
temp,
gap = 1;
while(gap < len/3) { //動態定義間隔序列
gap =gap*3+1;
}
for (gap; gap > 0; gap = Math.floor(gap/3)) {
for (var i = gap; i < len; i++) {
temp = ary[i];
for (var j = i-gap; j >= 0 && ary[j] > temp; j-=gap) {
ary[j+gap] = ary[j];
}
ary[j+gap] = temp;
}
}
return ary;
}
ShellSort(arr); // [1, 2, 3, 4, 5, 6, 15, 21, 63]
八、計數排序
排序規則:
1、找出待排序的數組中最大和最小的元素,然后建立一個數組C用於統計待排數組中最小元素到最大元素區間中每個元素出現次數;
2、統計數組中每個值為i的元素出現的次數,存入數組C的第i項;
3、對所有的計數累加(從C中的第一個元素開始,每一項和前一項相加);
4、反向填充目標數組:將每個元素i放在新數組的第C(i)項,每放一個元素就將C(i)減去1。
穩定性:穩定
排序動態示意:

代碼實現:
var arr = [3,4,1,2,21,5,15,6,63];
function CountSort(ary){
let obj={};
for(let i=0; i<ary.length; i++){
if(!obj[ary[i]]){
obj[ary[i]]=1;
}else{
obj[ary[i]]++;
}
}
let index=0;
//遍歷對象屬性名,按順序放回覆蓋原數組
for(let key in obj){
while(obj[key]>0){
ary[index]=Number(key);
obj[key]--;
index++
}
}
return ary;
}
CountSort(arr); // [1, 2, 3, 4, 5, 6, 15, 21, 63]
