一.利用排序进行查找中位数
基本思路:对数组进行排序,直接访问数组中位数
double MIDnum(vector<int>& array) {
if(array.empty())
return -1;
int midIndex = (array.size() - 1) / 2;
sort(array.begin(), array.end());
if (array.size() % 2 == 1) {
return (double)array[midIndex];
}
return ((double)array[midIndex] + (double)array[midIndex + 1]) / 2;
}
二.类似于快速排序,采用的是分而治之的思想.
基本思路:任意挑选一个元素,以该元素为基准点,将数组分为两部分.左部分都是小于基准点的,右部分都是大于基准点的.如果运气好的话,基准值正好就是中位数.
int partion(vector<int>& array, int begin, int end) {
int start = begin;
int key = array[begin];
while (begin < end) {
while (begin < end && array[end] >= key) {
end--;
}
while (begin < end && array[begin] <= key) {
begin++;
}
swap(array[begin], array[end]);
}
swap(array[start], array[begin]);
return begin;
}
double getNum(vector<int>& array, int midIndex) {
int left = 0;
int right = array.size() - 1;
int index = -1;
while (index != midIndex) {
index = partion(array, left, right);
if (index > midIndex) {
right = index - 1;
}
else if (index < midIndex) {
left = index + 1;
}
else
break;
}
return (double)array[index];
}
double midNum(vector<int>& array) {
if (array.empty()) {
return -1;
}
int midIndex = (array.size() - 1) / 2;
if (array.size() % 2 == 1) {
return getNum(array, midIndex);
}
return (getNum(array, midIndex) + getNum(array, midIndex + 1)) / 2;
}
三.利用最小堆查找中位数
基本思路:首先将数组的前(n+1)/2个元素建立最小堆.后序元素进行判断入堆或舍弃.下一个元素与堆顶元素进行对比,如果大于堆顶元素则删除堆顶元素,该元素入堆,否则什么都不做.
double MidNum(vector<int>& array) {
if(array.empty())
return -1;
int sz = array.size() / 2 + 1;
cout << sz << endl;
priority_queue<int,vector<int>,greater<int>> pq;
for (int i = 0; i < sz; i++) {
pq.push(array[i]);
}
for (int i = sz; i < array.size(); i++) {
if (array[i] > pq.top()) {
pq.pop();
pq.push(array[i]);
}
}
if (array.size() % 2 == 1) {
return (double)pq.top();
}
double val1 = double(pq.top());
pq.pop();
double val2 = double(pq.top());
return (val1 + val2) / 2;
}