3 6 最快效率求出亂序陣列中第k小的數

2021-10-02 00:04:26 字數 1298 閱讀 5411

以盡量高的效率求乙個亂序陣列中第k小的元素

演算法1用快排先將陣列排序,然後直接找第k個元素,時間複雜度為o(nlgn)

演算法2思路用分割槽查詢的思想,同樣有點排序的感覺,畢竟分割槽就是將小於主元的元素放左邊,大於主元的元素放右邊。

與排序完再查詢不同的是:

對於一次遞迴呼叫來說:

比如原來陣列10個元素,假設主元為第4個元素,如果位置(不是下標)k為3,則下次劃分為前5個元素,它的位置還是3;

如果k為6,則下次劃分為的陣列為第5-10個元素,它的位置為6-4=2,即第2個位置

時間複雜度分析

最好情況

每次主元的選取都選中整個陣列的中值,由於每次分割槽後只在原來的一半進行查詢,所以如果找到最後才找到的話(即待查位置的元素每次都不是主元),那時間複雜度為o(lgn)

最差情況

如果每次主元都選中邊界前乙個的話(左邊n-1個元素,右邊1個),如果找到最後才找到的話(即待查位置的元素每次都不是主元),那要進行n(1+n)/2 次運算,時間複雜度為o(n^2)

平均情況

三點分割槽法選取的中值比較合理,如果找到最後才找到的話(即待查位置的元素每次都不是主元),時間複雜度也是o(lgn)

**

int selectk(int* arr,int begin, int end,int k)
其中的分割槽函式要用到之前快排的分割槽函式,這裡用雙向掃瞄分割槽法,主元的選取採用3點中值法

/*快速排序-雙向掃瞄分割槽分割槽法

功能:選取乙個主元,將小於主元的數放陣列左邊,大於主元的數放右邊

//三點中值法確定主元

*/int partition2(int* arr,int begin,int end)

else if(arr[begin]<=arr[end]&&arr[begin>=arr[mid]])

else if(arr[begin]<=arr[end]&&arr[begin]<=arr[mid])

else

}else if(arr[begin]>=arr[end]&&arr[begin]>=arr[mid])

else

}int left=begin+1;

int right=end;

while(left<=right)

}int tmp=arr[begin];//交換主元到右指標的位置

arr[begin]=arr[right];

arr[right]=tmp;

return right;

}

求亂序陣列中第K大的值

投機取巧用函式進行處理,沒有從演算法角度思考 編譯成功60 還得再想想哪些案例沒有實現 include include include using namespace std int main 輸入為首行亂序數列,第二行為k值 int num vectorv1 while cin num int k...

亂序陣列中第k大的數(順序統計量)

該問題是順序統計量中十分經典的問題。使用快排中的分割槽法,將第k大的數排序。若雙向掃瞄分割槽加上三點中值法或絕對中值法,可以保證在 o n 時間裡找出第k大的數。補充 可以直接使用c stl中的nth element函式 一定注意使用形式!1 2 第k大的數 3 4int part int arr,...

從乙個無序陣列中求出第K大 小的數

這個題目可以作為練習寫大 小根堆的實現,不過貌似時間複雜度還是蠻高的。在洛谷上面一道模板題上面好像就超時了幾個點,不知道是不是我實現的問題。那麼除此之外,最容易想到的方法是先對該陣列進行排序,然後取出第k或max k數來。當選擇使用快排的時候,時間複雜度是 o nlogn 但還有一種更優的方法是利用...