手撕演算法 排序

2021-10-20 19:52:05 字數 3209 閱讀 2476

時間複雜度o(n

2)

o(n^2)

o(n2

) 空間複雜度 o(1) 穩定

從第乙個元素開始,認為左邊的序列是有序的,從有序部分的最後乙個向前比較,如果當前元素小於有序部分就交換,否則比較下乙個元素。

function

insertmerge

(arr)

else}}

return arr

}let arr =[1

,5,2

,4,3

,6,8

,7]console.

log(

insertmerge

(arr)

);

時間複雜度o(n

)o(n)

o(n)

空間複雜度 o(1) 不穩定

先建堆,然後每次讓陣列的最後乙個元素和第乙個元素進行交換,交換之後調整堆。注意每一輪交換之後找到乙個最大值放在了原陣列的末尾,下次交換這個元素不參與,相當於原陣列長度-1。

建堆是從最後乙個非葉子節點開始也就是 (len/2-)1,依次向上調整

調整的過程是拿目標節點和兩個子節點中最大的值比較,如果子節點大就交換,目標節點變成較大的子節點,否則,已符合堆結構,進行下一輪調整。

/**

* 完全二叉樹的最後乙個非葉子節點是 math.floor(len/2)-1

* 孩子節點的 2*i+1 和 2*i+2

*/function

heapsort

(arr)

return arr

}function

createheap

(arr)

}function

adjust

(arr, target, len)

if(arr[target]

< arr[i]

)else}}

let arr =[1

,3,2

,5,3

,6,2

,0]console.

log(

heapsort

(arr)

)

時間複雜度o(nlogn) 空間複雜度o(n) 穩定

分割將陣列從分成左右兩個陣列,然後遞迴的分割,知道陣列的長度小於2

合併當左右兩個陣列有序的時候,合併兩個陣列。建立乙個空陣列temp,比較左右兩邊的陣列,小值加入到temp中。若左右陣列有乙個為空,那麼此時另乙個陣列一定大於temp中的所有元素,直接將其所有元素加入temp。

然後將tmp的值一一傳遞給原陣列

function

mergesort

(arr, left, right, tmp)

function

merge

(arr, left, right, tmp)

else

}while

(leftindex <= mid)

while

(rightindex <= right)

tmpindex =

0for

(let i = left; i <= right; i++)}

let arr =[3

,4,2

,1,5

,0]mergesort

(arr,

0, arr.length-1,

)console.

log(arr)

時間複雜度:平均o(nlogn),最壞o(n

2)

o(n^2)

o(n2

),實際上大多數情況下小於o(nlogn)

空間複雜度:o(logn)(遞迴呼叫消耗)

快速排序是每次找到乙個基準元素,左右兩邊分別和基準元素比較,如果左邊元素小於基準元素,左指標向右移動,如果右邊元素大於基元素,右指標向左移動。否則,就交換左右兩邊的元素。當左右指標相遇,相遇處即是基準元素所在的位置,將基準元素交換到該位置。基準元素切分出了左右兩邊,左邊都比基準元素小,右邊都比基準元素大。

function

quicksort

(arr, left, right)

while

(i < j && arr[i]

<= pivot)

swap

(arr, i, j)

}swap

(arr, left, i)

quicksort

(arr, left, i-1)

quicksort

(arr, i+

1, right)

}function

swap

(arr, i, j)

const arr =[3

,2,4

,1,5

,6,8

]quicksort

(arr,

0, arr.length-1)

console.

log(arr)

時間複雜度o(n

2)

o(n^2)

o(n2

) 空間複雜度o(1) 不穩定

每次將乙個最大值沉底,下一次比較不考慮沉底的元素

function

bubble

(arr)}}

return arr

}const arr =[4

,5,2

,1,3

]bubble

(arr)

console.

log(arr)

時間複雜度o(n

2)

o(n^2)

o(n2

) 空間複雜度o(1) 不穩定

每次選出最小的元素放在未排序的部分的首位

/**

* 每次選出最小的元素放在首位

*/function

selectsort

(arr)

}[arr[i]

, arr[minindex]]=

[arr[minindex]

, arr[i]]}

}const arr =[1

,3,2

,1,5

,6,7

]selectsort

(arr)

console.

log(arr)

演算法 手撕堆排序

時間複雜度 o n logn o nlogn o nlog n 但是實際軟開中,快排效能更好。堆性質 堆排序 從小到大,利用最大堆和陣列 從後往前堆化陣列元素,此時最大元素在首位置 交換元素堆化 include include using namespace std void heapsort in...

Python手撕排序演算法

氣泡排序 公升序 歸併排序 公升序 分而治之 每次在若干無序資料中查詢最小數,放在無序資料的首位。1.從n個元素的列表中找最小值及其下標,與第乙個元素交換 2.從第二個元素開始的n 1個元素中找最小值及其下標,與第二個元素交換 3.以此類推,n 1輪後即為排好序的資料 a 49 38,65 97,7...

手撕演算法 adaboost

adaboost是典型的boosting演算法。boosting演算法的核心思想是 上乙個模型對單個樣本 的結果越差,下個模型越重視這個樣本 增大該樣本的權重,加大模型 錯的成本 提公升樹就是每個模型都是決策樹,提公升樹種效果比較好的是gbdt和xgboost,入門是adaboost。adaboos...