演算法設計:如何求數組中第i大 或 第i小的數 (續上)

來源:互聯網
上載者:User

http://blog.csdn.net/yanzi1225627/article/details/8111806 、http://www.eyeandroid.com/thread-9629-1-1.html這裡討論了求第二大的思路。現在研究如果是第i大怎麼辦?
先清晰一下概念,如果有個數組a[6] = 2 60 10 32 84 6; 那麼第1大的數是最大值84, 第2大是60, 第3大是32, 第1小是2, 第二小是6., 第三小是10, 第4小是32. 也即如果讓找第i小, 等價於找第n-i+1大。 如果讓找第i大, 等效於找第n+1-i小,兩者可以互換。

  思路還是快速排序,為了方便我們假設找第i小的數。

先看快速排序的partition函數:

int partition(int a[], int i, int j){int pivot = a[i];while(i<j){while(i<j && a[j] >= pivot)j--;if(i<j)a[i++] = a[j];while(i<j && a[i] <= pivot)i++;if(i<j)a[j--] = a[i];}a[i] = pivot;return i;}

下面就是找第i小的數:

int find_n_min(int a[], int low, int high, int n_min){int p = partition(a, low, high);if(p-low+1 == n_min)return a[p];if(p-low+1 > n_min) return find_n_min(a, low, p-1, n_min);else return find_n_min(a, p+1, high, n_min-(p-low+1));}

    解釋下思路,先找到劃分的基準索引p,p左邊的都是小於a[p]的, 那麼可以得到a[p]就是第p-low+1小的數。 為了方便舉個例子, 如果經過一次partition函數之後,數組為 5 3 6 12 50 21,p = 3,也就是a【3】 = 12是劃分的基準,那麼a【3】肯定是3-0+1 = 4,第4小的數。

       如果p-low+1 >n_min, 比如,p-low+1 = 5, a[p]是第5小的數,而程式讓找第2小的數,這個時候需要遞迴到 【low, p-1】區間去找第2小的數,這個舉了例子應該不難理解了。

         對應的如果小於n_min的話,就要從p+1開始到high區間進行調用搜尋第n_min - (p - low +1)小的數。 

     這裡需要注意兩個事,

第一,遞迴的時候前面不要忘了return

第二,遞迴的時候新的區間一定是【low, p-1】,這個減一一定不能少!為什嗎?這是我們這裡採用的a[low]作為基準值,而http://blog.csdn.net/yanzi1225627/article/details/8109035這裡採用的是(high
+ low)/2作為基準值,所以遞迴的時候,臨界區間的一邊沒有減一。

       為了清晰說明這個問題,我們舉個例子,假設初始數組a[] = 12 3 6 5 50 21,我們要找第3小的數。

第一次進到partition函數後,以12作為基準,partition函數返回的p = 3,數組這個時候更新成5 3 6 12 50 21,因為p-0+1 = 4大於3,所以索引從0到2搜尋即可!如果上面臨界區間沒有減1,也就是從0到3搜尋的話(數組為5 3 6 12),我們看看會有啥後果?

第二次進到partion,基準為5,函數返回的p = 1,數組更新成3 5 6 12,由於p-0+1 = 2,因此需要進到第三次partition,臨界區間不加1的話(正確的應該從p+1開始),就是從p(也就是1)到3,數組為 5 6 12,問題轉換為在5 6 12中找第1小的數

第三次進到partion,壞就壞在這,因為是用的第一個數5作為基準的,所以這個partition返回的p = 1. 也就是5,所以最終函數的找到的第三小的數也就是5.這顯然是錯誤的!因此,在這裡用a[low]作基準的話,臨界區間必須減1。如果像這裡http://blog.csdn.net/yanzi1225627/article/details/8109035用mid
= (low +high)/2坐的基準,更新後的區間則不用減一。

     至此,在數組中找第i小的問題解決了,如果要找第i大的數只需將參數轉化下就中,這在開頭交代過。或者將上面函數裡的p-low+1 改成high-p+1,a[p]為第i大的數,簡單調整下即可。

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.