尋找n個數的第k項只需要對它們進行排序,然後找到即可。但是耗時o(nlongn);在書上看到了很好的方法,想著實現一下:
輸入:乙個數列a,乙個整數k
輸出:數列a中第k小的數
我們假定陣列的乙個數v,現在把陣列a分成三份。
a2 =
a3= }
例如任意乙個陣列a=;
假設v等於5 a1=2 4 1 ; a2=5 5; a3=36 21 8 13 11 20
搜尋範圍就減小了。現在只需要在a的三個子集中尋找,如果想尋找第8小元素,他一定在a3中,同理可以得到遞迴
f(a1,v) if k<=|a1|
f(a,k)= printf(a2) if k==|a1+a2|
f(a3,v-|a1|-|a2|) if k>|a1+a2|
思路清晰後,重要的是v的選取,因為v的選取決定了整個演算法的複雜度。最理想的情況就是|a1|,|a3|=1/2|a|
如果我們一直背運,我們選出來的v很可能一直是陣列的最大元素或者最小元素,那麼演算法需要執行
n+(n-1)+(n-2)+....+n/2=o(n*n)
但是這種情況出現的概率非常低
最好的情形是選取的v正好能把陣列一分為二,從而複雜度為o(n)
從o(n)->o(n*n) 演算法的平均執行時間基本符合最佳執行時間
當然**肯定有瑕疵。才接觸分治 又不好的地方大家一起交流下
#include#includeusing namespace std;
void f(int a, int zuo, int you, int v)
//system("pause");
//printf("\n");
int a1[10] = , a2[10] = , a3[10] = ;
int num = v / 2;
int j = 0, k = 0, l = 0;
for (int i = zuo; i <= you; i++)
if (v <= j)
else if (v>j&&v<=k+j)
else if (v > j + k)
}int main();
int b[10] = ;
//int n = 8;
int k;
//scanf("%d", &k);
printf("偶數的第n小的值分別為:\n");
for (int k = 1; k <= 8;k++)
f(a, 0, 7,k);
printf("\n奇數的第n小的值分別為:\n");
for (int k = 1; k <= 9; k++)
f(b, 0, 8, k);
return 0;
}
尋找單個無序陣列中第K小的數字
1 排序 對陣列進行排序 然後前k個元素就是需要查詢的元素,排序的方法可以採用快速排序,但是我們知道在快速 排序中如果已經是有序的陣列,採用快速排序的時間複雜度是o n 2 為了解決這種問題,通常選擇隨機選擇乙個 陣列值pivot作為基準,將陣列分為s1 pivot和s2 pivot,這樣就能避免快...
快速排序 尋找無序陣列中的第k大的數
思路是利用快速排序 因為快速排序的分治思想可以將查詢的範圍縮小 快速排序的思想 low為陣列的起始點,high為陣列的尾部點。交替掃瞄 1.固定陣列的第乙個數為定點,從陣列的尾部high開始往左查詢,直到第乙個比定點小的數,和定點交換,因此當前點為空 high 2.從陣列的起始處,low找到第乙個比...
尋找無序陣列的中位數
題目 求乙個無序陣列的中位數。如 的中位數為5,的中位數為4和5。void findmidnum1 int arr,int size for int j size 1 2 1 j size j if size 1 奇數個元素 cout 中位數 pq.top endl else 1.將陣列元素平均分配...