5.查詢最小的 k 個元素(陣列)
題目:輸入 n 個整數,輸出其中最小的 k 個。
例如輸入 1,2,3,4,5,6,7 和 8 這 8 個數字,則最小的 4 個數字為 1,2,3 和 4。
演算法裡面學過查詢第k小的元素的o(n)演算法
試著實現了一下:
注意new 初始化二維陣列的方式
int (* a)[5] = new int[8][5];
/*5.查詢最小的 k 個元素(陣列)
題目:輸入 n 個整數,輸出其中最小的 k 個。
例如輸入 1,2,3,4,5,6,7 和 8 這 8 個數字,則最小的 4 個數字為 1,2,3 和 4。
*/#include
#include
using
namespace
std;
bool compare(int a, int b) //
降序排列
//找到 一共有 n個 元素的 陣列s 中 第k小 的數字 整個演算法中,對除以5後餘下的數字都做了特殊處理
int select(int * s, int k, int
n)
int subn = n/5 + ((n % 5 == 0) ? 0 : 1
);
int subnn = n/5
;
int (* subs)[5] = new
int[subn][5
];
for (int i = 0; i < subnn; i++)
sort(subs[i], subs[i] + 5, compare); //
5個一組,每組從大到小排序
}
for (int j = 0; j < n % 5; j++)
sort(subs[subn - 1], subs[subn - 1] + n % 5
, compare);
int * m = new
int[subn];
for (int i = 0; i < subn; i++)
int mn =subnn;
int m = select(m, mn/2 + (mn % 2 == 0) ? 0 : 1
, mn);
delete m;
int * s1 = new
int [n]; //
存放小於等於m的數字
int * s2 = new
int[n];
int s1n = 0; //
記錄有多少小於等於m的數字
int s2n = 0
;
//找到相應的s1 與 s2中的元素
for (int i = 0; i < subnn; i++)
else
}else}}
else
else
}else}}
}if (subnn != subn) //
多餘的數字特別處理
else}}
if (k ==s1n)
else
if (k else
delete s1;
delete s2;
}int
main()
;
int m = select(a, 7, 8
);
return0;
}
不過,我的**看起來好長,好難受啊...
網上有用堆做的,對堆不是很了解,要補一下知識。
看了用堆的方法的原理,理論上會比我現在實現的這個演算法慢一點
方法是用堆維護k個最小元素
下面來自:
咱們再進一步想想,題目沒有要求最小的k個數有序,也沒要求最後n-k個數有序。既然如此,就沒有必要對所有元素進行排序。這時,咱們想到了用選擇或交換排序,即:
1、遍歷n個數,把最先遍歷到的k個數存入到大小為k的陣列中,假設它們即是最小的k個數;
2、對這k個數,利用選擇或交換排序找到這k個元素中的最大值kmax(找最大值需要遍歷這k個數,時間複雜度為o(k)
);
3、繼續遍歷剩餘n-k個數。假設每一次遍歷到的新的元素的值為x,把x與kmax比較:如果x < kmax
,用x替換kmax,並回到第二步重新找出k個元素的陣列中最大元素kmax『;如果x >= kmax
,則繼續遍歷不更新陣列。
每次遍歷,更新或不更新陣列的所用的時間為o(k)
或o(0)
。故整趟下來,時間複雜度為n*o(k)=o(n*k)
。
更好的辦法是維護容量為k的最大堆,原理跟解法二的方法相似:
這樣下來,總的時間複雜度:o(k+(n-k)*logk)=o(n*logk)
。此方法得益於堆中進行查詢和更新的時間複雜度均為:o(logk)
(若使用解法二:在陣列中找出最大元素,時間複雜度:o(k))
。
堆的實現**:來自
publicstatic
void findkmin(int sort, intk)
for (int i = k, len=heap.length; i < len; i++)
}console.writeline(
"the min element =
",k);
for (int i = 0; i < k; i++)
} private
static
void reheap(int heap, int rootindex, int
lastinddex)
}if (orphan else
}heap[rootindex] =orphan;
}
查詢最小的k個元素
題目 輸入n個整數,輸出其中最小的k個。演算法思想,要是將n個數排序然後輸出前k個,方法很簡單,但計算量比較大,為o nlogn 要是新建乙個有k個元素陣列,在陣列不滿時,將每乙個輸入的資料存入陣列。若陣列滿了,則比較輸入的資料與陣列中最大元素的大小,來決定接下來幹什麼,接下來幹什麼,我語言表達能力...
查詢最小的k個元素
查詢最小的k個元素 題目 輸入n個整數,輸出其中最小的k個。例如輸入1,2,3,4,5,6,7和8這8個數字,則最小的4個數字為1,2,3和4。1 輸入元素,並排序 2 輸出前k個元素 排序 採用高效的排序方法,如 快速排序,歸併排序等 方法一 採用最簡單的方法 include include in...
查詢最小的k個元素
題目 輸入n個整數,輸出其中最小的k個數 例如 1 2 3 4 5 6 7 8 這8個數字,則最小的4個數字為1,2,3,4,第一種 直接對其先排序,再取頭幾個數 這樣最快是nlogn 快排或者堆排 include using namespace std void partsort int a,in...