演算法思考 topk問題堆排序 快速排序比較

2021-09-11 12:20:14 字數 2541 閱讀 5214

快速排序求解

這種演算法利用了快速排序的主要思想:每次呼叫快速排序的partition函式後將會得出乙個數n的最終位置,比較n及其右邊所有數的總個數與目標個數k

若大於k,則對數n右邊的數構成的陣列呼叫partition函式;

若等於k,則說明n及其右邊的數就是我們想要得到的那k個數,排序結束;

若小於k,這說明最終的k個數中還包含了n左邊的數,對n左邊的數構成的陣列呼叫partition函式。

pyhton**:

import numpy as np

defqselect

(a, k):if

len(a)

< k:

return a

pivot = a[-1

] tmp = a[:-

1][a[:-1

]>=

[pivot]

] right = np.insert(tmp,

0, pivot)

try:

rlen =

len(right)

except

: rlen =

1if rlen == k:

return right

if rlen > k:

return qselect(right, k)

else

: left =

[x for x in a[:-

1]if x < pivot]

, right)

l = np.random.randint(0,

10000

, size=

10000

)k =

100qselect(l, k)

利用快速排序解決topk問題時,速度非常快,但是缺點它在陣列中直接交換資料,所以要用乙個陣列來儲存所有的資料,當資料量十分龐大時將占用驚人的記憶體,屬於用空間換時間的演算法。

堆排序這種演算法的大致思路為:首先初始化乙個大小為k的小根堆,然後遍歷陣列,每遍歷乙個數就將其與堆的根節點相比較,若比根節點大,則將其與根節點交換變更新堆結構。當陣列遍歷完成時堆中儲存的就是我們想要的結果。

pyhton**:

import numpy as np

defsift

(l, low, hight)

:# 調整堆結構

tmp = l[low]

i = low

j =2* i +

1while j <= hight:

# 情況2:i已經是最後一層

if j +

1<= hight and l[j +1]

< l[j]

:# 右孩子存在並且小於左孩子

j +=

1if tmp > l[j]

: l[i]

= l[j]

i = j

j =2* i +

1else

:break

# 情況1:j位置比tmp小

l[i]

= tmp

deftop_k

(l, k)

: heap = l[

:k]# 建堆

for i in

range

(k //2-

1,-1

,-1)

: sift(heap, i, k -1)

for i in

range

(k,len

(l))

:if l[i]

> heap[0]

: heap[0]

= l[i]

sift(heap,

0, k -1)

for i in

range

(k -1,

-1,-

1): heap[0]

, heap[i]

= heap[i]

, heap[0]

sift(heap,

0, i -1)

return heap

l = np.random.randint(0,

10000

, size=

10000

)k =

100top_k(l, k)

利用堆排序解決topk問題時,速度是所有演算法中除了快速排序之外最快的,它的突出優點就是不論資料量有多大,它的空間複雜度總是常數級的,在處理大資料時常將資料分塊打包後分別利用堆排序進行篩選,再將篩選結果進行比較,選出我們想要的最終結果。

兩種演算法直觀比較:

縱座標為耗時,橫座標為初始序列長度,數值取值範圍為[0,999999999],k(即最終篩選出的數值個數)為100,

堆排序與topK問題

找出乙個有10億數字陣列中,前k個最大值 第一步 hash去重 解法1 劃分法 def partition l,left,right low left if left right key l left high right while low high while low high and l hi...

堆排序 TOPK問題 C

現在有n個數,設計演算法得到前k大的數。k 首先從原列表擷取前k個元素,組成乙個新列表。然後將這個新列表構建成乙個小根堆,那麼根就新列表中最小的數。接著繼續從原列表取出k以後的元素,和小根堆根比對,如果比根小,那麼肯定不屬於前k大的數,如果比根大,替換根,然後做一次向下調整,根重新變成新列表最小的數...

演算法基礎 二 topK問題 堆排序應用

package algorithm topk問題 例如,有1億個浮點數,如何找出其中最大的10000個?運用堆排序解決top k問題 top k問題就是在一堆資料中選擇前k大 前k小 的資料。做法有許多,可以先把所有資料排序,然後選前k個。然後用堆排序解決top k問題則不用先全部排序,只需維護乙個...