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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

线性时间选择

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

問題:給定線性序集中n個元素和一個整數k,1≤k≤n,要求找出這n個元素中第k小的元素。(這里給定的線性集是無序的)。(如果將這個線性集先排好序,則排在第k個位置的元素即為要找的元素)

方法:線性時間選擇隨機劃分法可以模仿隨機化快速排序算法設計。基本思想是對輸入數組進行遞歸劃分,與快速排序不同的是,它只對劃分出的子數組之一進行遞歸處理。

可以按以下步驟找到滿足要求的劃分基準:

  • 將n個輸入元素劃分成n/5(向上取整)個組,每組5個元素,最多只可能有一個組不是5個元素。用任意一種排序算法,將每組中的元素排好序,并取出每組的中位數,共n/5(向上取整)個。

  • 遞歸調用select來找出這n/5(向上取整)個元素的中位數。如果n/5(向上取整)是偶數,就找它的2個中位數中較大的一個作為劃分基準。

  • 思考草圖:



    (每一組進行排序,最后不足5個的忽略)
    ————————————————————————————

    (找出每一組的中位數)
    ————————————————————————————

    (把中位數提出來)
    ————————————————————————————————————

    (找到中位數的中位數)

    ————————————————————————————————————

    (交換位置作為“軸”,借鑒快速排序)


    ————————————————————————————



    (找到k)

    #include<iostream> #include<ctime> #include<cstdlib> using namespace std;int partition(int a[], int p, int r){int i = p;int j = r + 1;int x = a[p]; //設置軸while(true){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 partition(int a[], int p, int r, int x){ //重載partition方法 int i = p-1;int j = r + 1;while(true){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; }void quickSort(int a[], int p, int r){if(p < r){int q = partition(a, p, r);quickSort(a, p, q - 1); //左邊排序quickSort(a, q + 1, r); //} }int select(int a[], int p, int r, int k){if(r - p < 75) {quickSort(a, p , r); //其他排序也可以 return a[p+k - 1];}for(int i = 0; i <= (r-p-4) / 5; i++){ //r-p-4表示最后一組的中位數所在組數 (有幾組就有幾個中位數,所以(r-p-4)/5也可以表示中位數個數) quickSort(a, p+i*5, p+i*5+4); //將元素每5個分成一組,分別排序swap(a[p+i], a[p+i*5+2]); //并將該組中位數與a[p+i]交換位置使所有中位數都排列在數組最左側,以便進一步查找中位數的中位數 }//找中位數的中位數int x = select(a, p, p+(r-p-4) / 5, (r-p-4) / 10); //(r-p-4) / 10:中位數的中位數的下標 int pivot = partition(a, p, r, x);int j = pivot-p + 1;if(k <= j)return select(a, p, pivot, k);elsereturn select(a, pivot + 1, r, k - j); }int main(){//初始化數組 int a[100];srand((int)time(0)); // 產生隨機種子 把0換成NULL也行for(int i = 0; i < 100; i++){a[i] = rand() % 100;}int k;cout << "please input k: " << endl; cin >> k;cout << select(a, 0, 99, k) << endl;for(int i = 0; i < 100; i++){cout << a[i] << " ";} cout << endl << "-------------檢驗組----------"<< endl;quickSort(a, 0, 99);for(int i = 0; i < 100; i++){cout << "a[" << i << "]="<< a[i] << " ";} }

    總結

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

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