前端演算法系列 排序

2021-10-14 05:46:54 字數 3839 閱讀 8527

排序演算法

平均時間複雜度

最壞時間複雜度

空間複雜度

是否穩定

氣泡排序

o(n²)

o(n²)

o(1)

是選擇排序

o(n²)

o(n²)

o(1)

不是直接插入排序

o(n²)

o(n²)

o(1)

是快速排序

o(nlogn)

o(n²)

o(logn)

不是希爾排序

o(nlogn)

o(n^s)

o(1)

不是冒泡、選擇、直接 排序需要兩個for迴圈,每次只關注乙個元素,平均時間複雜度為o(n²)(一遍找元素o(n),一遍找位置o(n))

快速、歸併、希爾、堆基於二分思想,log以2為底,平均時間複雜度為o(nlogn)(一遍找元素o(n),一遍找位置o(logn))

是否穩定?

穩定性:通俗的講有兩個相同的數a和b,在排序之前a在b的前面,而經過排序之後,b跑到了a的前面,對於這種情況的發生,我們管他叫做排序的不穩定性,而快速排序在對存在相同數進行排序時就有可能發生這種情況(不穩定性會導致重繪重排問題)

如果不考慮穩定性,快排似乎是接近完美的一種方法,但可惜它是不穩定的

1)比較所有相鄰元素,如果第乙個比第二個大,則交換它們

2)一輪下來,可以保證最後乙個數是最大的

3)執行n-1輪,就可以完成排序

// 時間複雜度:o(n^2) 兩個巢狀迴圈

array.prototype.

bubblesort

=function()

}}}const arr =[5

,4,3

,2,1

]arr.

bubblesort

()

原理:找出最小值得索引,再跟第乙個索引進行交換

1)假設第乙個元素就是最小的,定義個變數min放置索引0,拿著最小元素依次進行比較,得到最小索引處

2)拿此時最小索引跟剩餘的元素做比較,得到最小索引處

3)交換第一索引處和最小索引處的值

// 時間複雜度:o(n^2) 兩個巢狀迴圈

array.prototype.

selectionsort

=function()

}if(indexmin!==i)}}

const arr =[5

,4,3

,2,1

]arr.

selectionsort

()

1)把所有元素分為兩組,已排序和未排序的

2)找到未排序中的第乙個元素,向已排序的進行插入(倒敘遍歷已排序的,找到小於待插入元素,就把待插入元素放到這個位置,其他元素向後移動一位)

從第二個數開始往前比,比它大就往後排

// 時間複雜度:o(n^2) 兩個巢狀迴圈

array.prototype.

insertsort

=function()

this

[j+1

]= tmp // 迴圈到最後,改變開始往前比較的值}}

const arr =[5

,4,3

,2,1

]arr.

insertsort

()

原理:把原陣列進行分組,分完組之後,對每一組陣列進行插入排序

1)選定乙個增長量,按照增長量h作為資料分組的依據來分組

2)對分好組的每一組資料完成插入排序(如果左邊比右邊大就交換元素)

3)減小增長量,最小減為1,重複第二步操作

// 增長量h的確定規則

var h =

1while

(h陣列長度/2)

// 迴圈結束後我們就可以確定h的最大值

h的減小規則為: 每次迴圈為h/

2 h = h/

2

array.prototype.

shellsort

=function()

// 陣列元素i和j交換位置

function

exch

(a,i,j)

// 2.希爾排序

while

(h>=1)

else}}

// 2.2 減小增量值

h= math.

floor

(h/2)}

return arr

}const arr =[5

,8,3

,0,1

,4,6

]arr.

shellsort()

console.

log(arr)

原理:把一組資料分為多組資料,如果還可以繼續分,就繼續分組,分到不能分為止再進行歸併(在歸併裡面進行排序的)

/** 分的時間複雜度:o(logn)

* 合的時間複雜度:o(n)

* 時間複雜度:o(n*logn)

*/array.prototype.

mergesort

=function()

else

if(orderleft.length)

else

if(orderright.length)

}return res

}const res =

rec(

this

) res.

foreach

((n,i)

=>);

}const arr =[5

,4,3

,2,1

]arr.

mergesort

()

/** 遞迴的時間複雜度是o(log(n))

* 分割槽操作的時間複雜度是o(n)

* 時間複雜度:o(n*logn)

*/array.prototype.

quicksort

=function()

// 遞迴出口

const left =

;// 左側陣列

const right =

;// 右側陣列

const mid = arr[0]

;// 基準

for(

let i =

1; i < arr.length; i++

)else

}return

[...

rec(left)

, mid,

...rec

(right)];

// 返回遞迴後的左 + 基準 + 右 的拼接陣列};

const res =

rec(

this);

res.

foreach

((n, i)

=>);

// 將res的值 賦值給arr};

const arr =[5

,4,3

,2,1

]arr.

quicksort

()

排序演算法系列

概述 概念 排序是計算機內經常進行的一種操作,其目的是將一組 無序 的記錄序列調整為 有序 的記錄序列。排序分為內部排序和外部排序。若整個排序過程不需要訪問外存便能完成,則稱此類排序問題為內部排序。反之,若參加排序的記錄數量很大,整個序列的排序過程不可能在記憶體中完成,則稱此類排序問題為外部排序。排...

前端演算法系列 演算法總結

鍊錶樹 堆map 排序和搜尋 演算法設計思想 七分理解,三分記憶 技巧 三指標 反轉 回文 反轉後相同 中間劈開對稱性 技巧 雙指標 場景 最大 最小值 使用輔助棧,當大於或小於棧頂時才push進去,然後便可取棧頂的值作為最大 小值 煉表處理 合併 刪除 鍊錶反轉 鍊錶成環 完全二叉樹 可以不需要有...

排序演算法系列 選擇排序

選擇排序可以說是眾多排序演算法中,最基礎 最直觀的乙個演算法了。它的思想十分簡單 遍歷列表,找出最小的乙個數,記下索引 將最小的數新增到新的列表中,同時刪除原陣列中的數 重複第一步 舉個例子 假如現在有乙個無序陣列disorder arr 4,2,19,10,1 和乙個空陣列order arr 第一...