在o(n)時間範圍內找出陣列a[n]中位數相鄰的k個數字
思路:簡單的思路是先找出中位數(n+1)/2然後依次找第(n+1)/2-1小數字、(n+1)/2-2小數字、(n+1)/2-3.小數字。。。。(n+1)/2-k/2小數字,再找第(n+1)/2+1小數字、(n+1)/2+2小數字、(n+1)/2+3.小數字。。。。(n+1)/2+(k+1)/2小數字。但是該演算法時間複雜度為o(kn)。
改進思路為:先找中位數,將陣列按照中位數進行分割,陣列的前半部分找第(n-1)/2-k/2小的數字,按照該數字對前半部分進行分割,則該數字到中位數之前的數字有k/2個數字,這些數字為與中位數相鄰且小於中位數的前k/2個數字。陣列的後半部分找出第(k+1)/2小的數字,然後按照該元素對後半部分進行分割,則中位數後一元素到該元素的(k+1)/2個元素為與中位數相鄰且大於中位數的數字。該演算法共呼叫三次分割選擇函式select,而該函式的時間複雜度為o(n),所以時間複雜度為o(n)。其具體**如下:
//例題9.2中的演算法的期望時間複雜度為o(n),而在9.3的例題中的最壞執行時間複雜度為o(n)。
//該演算法實現思路是將陣列每五個元素分為一組,最後一組可能不足五個。
//選出每一組中的中位數,然後選出這些中位數的中位數。根據這個中位數對陣列進行劃分為兩組。
//然後再按照9.。2中的方法遞迴呼叫劃分尋找第i小的數。
//該演算法的對比於9.2的改進之處在於對partition方法進行了優化,而不是隨進選擇陣列進行劃分。
#includeusing namespace std;
//插入排序不解釋
void insert_sort(int a,int p,int r)
if((i+4)<=r)
else
i+=5;
} j=j-1;
//對b中的元素進行排序
insert_sort(b,0,j);
//找到b中的中位數
num=b[j/2];
//將a中的num與a[r]替換
for(i=0;i<=r;i++)
temp=a[i];
a[i]=a[r];
a[r]=temp;
//根據找到的num對陣列進行劃分
j=p-1;
for(i=p;i=p+(length-1)/2-(k)/2;i--)
//將中位數元素後乙個元素到q賦給b的後半部分
j=(k)/2;
for(i=p+(length-1)/2+1;i<=p+(length-1)/2+(k+1)/2;i++) }
int main()
; int b[100];
selectkthnearthemiddle(a,b,0,14,5);
for(int i=0;i<5;i++)
{ cout<
演算法導論 第九章
這章介紹了中位數和順序統計學 中位數即乙個序列中最中間的數字,在快速排序中非常有意義,在其它的一些應用中也很有效,因為可以2分序列,這樣會有更好的效率。這章主要介紹如何不排序來找到序列的順序,由於不需要排序,可以減少很多比較的操作,最終可以獲得一些線性的演算法,得到排名第i的數字。演算法的基礎是首先...
第九章 習題
一 填空題 1 執行異常,可以 預料 但不能避免,它是由 系統執行環境 造成的。2 在小型程式開發中,一旦發生異常所採取的方法一般是 將程式立即中斷執行,從而無條件釋放所有資源 3 c 的異常處理機制使得異常的引發和處理 不必 在同一函式中。4 如果預料某段程式 成對某個函式的呼叫 有可能發生異常,...
第九章 習題
一 填空題 1 執行異常,可以 預料 但不能避免,它是由 系統執行環境 造成的。2 在小型程式開發中,一旦發生異常所採取的方法一般是 將程式立即中斷執行 3 c 的異常處理機制使得異常的引發和處理 不必 在同一函式中。4 如果預料某段程式 成對某個函式的呼叫 有可能發生異常,就將它放在 try語句塊...