日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

算法:线性时间选择

發布時間:2023/12/9 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法:线性时间选择 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

定義:給定線性序集中n個元素和一個整數k,1≤k≤n,要求找出這n個元素中第k小的元素。

(1)在某些特殊情況下,很容易設計出解選擇問題的線性時間算法。如:當要選擇最大元素或最小元素時,顯然可以在O(n)O(n)O(n)時間完成。(一趟比較即可)

(2)一般的選擇問題,特別是中位數的選擇問題似乎比最小(大)元素要難。但實際上,從漸近階的意義上,它們是一樣的。也可以在O(n)O(n)O(n)時間完成。

步驟:

(1)將n個輸入元素劃分成n/5(向上取整)個組,每組5個元素,最多只可能有一個組不是5個元素。用任意一種排序算法,將每組中的元素排好序,并取出每組的中位數,共n/5(向上取整)個。
(2)遞歸調用select來找出這n/5(向上取整)個元素的中位數。如果n/5(向上取整)是偶數,就找它的2個中位數中較大的一個。以這個元素作為劃分基準。
劃分策略示意圖:

注意:

  • 設中位數的中位數是x,比x小和比x大的元素至少3*(n-5)/10個,原因:
    • 3*(n/5-1)*1/2
    • 3—中位數比x小的每一組中有3個元素比x小
    • n/5-1—有5個數的組數
    • 1/2—大概有1/2組的中位數比x小
  • 而當n≥75時,3(n-5)/10≥n/4所以按此基準劃分所得的2個子數組的長度都至少縮短1/4,也就是說,長度最長為原長度的3/4。
  • 如圖,劃分的部分左上是肯定比x小的(大概占1/4)右下是肯定比x大的(大概占1/4)左下和右上不確定,就算這兩部分同時不比x小或比x大,劃分成的子區間也能至少縮短1/4!

    代碼如下:

    #include <bits/stdc++.h> using namespace std;void bubbleSort(int a[],int p,int r) {for(int i=p; i<r; i++){for(int j=i+1; j<=r; j++){if(a[j]<a[i])swap(a[i],a[j]);}} }int Partition(int a[],int p,int r,int val) {int pos;for(int q=p; q<=r; q++){if(a[q]==val){pos=q;break;}}swap(a[p],a[pos]);int i=p,j=r+1,x=a[p];while(1){while(a[++i]<x&&i<r);while(a[--j]>x);if(i>=j)break;swap(a[i],a[j]);}a[p]=a[j];a[j]=x;return j; }int Select(int a[],int p,int r,int k) {if(r-p<75){bubbleSort(a,p,r);return a[p+k-1];}//找中位數的中位數,r-p-4即上面所說的n-5for(int i=0; i<=(r-p-4)/5; i++) //把每個組的中位數交換到區間[p,p+(r-p-4)/4]{int s=p+5*i,t=s+4;for(int j=0; j<3; j++) //冒泡排序,從后開始排,結果使得后三個數是排好順序的(遞增){for(int n=s; n<t-j; n++){if(a[n]>a[n+1])swap(a[n],a[n-1]);}}swap(a[p+i],a[s+2]);//交換每組中的中位數到前面}//(r-p-4)/5表示組數-1,則[p,p+(r-p-4)/5]的區間長度等于組數int x=Select(a,p,p+(r-p-4)/5,(r-p+1)/10);//求中位數的中位數/*(r-p+1)/10 = (p+(r+p-4)/5-p+1)/2*/int i=Partition(a,p,r,x),j=i-p+1;if(k<=j)return Select(a,p,i,k);else return Select(a,i+1,r,k-j); } int main() {int x;//數組a存了0-79int a[80]= {3,1,7,6,5,9,8,2,0,4,13,11,17,16,15,19,18,12,10,14,23,21,27,26,25,29,28,22,20,24,33,31,37,36,35,39,38,32,30,34,43,41,47,46,45,49,48,42,40,44,53,51,57,56,55,59,58,52,50,54,63,61,67,66,65,69,68,62,60,64,73,71,77,76,75,79,78,72,70,74,};cin>>x; printf("第%d大的數是%d\n",x,Select(a,0,79,x)); }

    運行效果:

    總結

    以上是生活随笔為你收集整理的算法:线性时间选择的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。