目录
一、目的
能够正确地应用分治算法解决众数问题,对边界值测试效果,能正确得分析算法时间复杂度。
二、设计思路
将求一个数组中的众数,分解成若干个求一个数组中中位数数量的小问题,利用分治算法求解各个小问题。
三、算法描述:
- 用algorithm 库中的sort 函数将随机数数组排序
- mid =(right +left)/2计算出中位数
- 检索出mid左侧相同的数数量sum
- 检索出mid右侧相同的数数量累加sum
- 比较sum与maxsum
- 若大于则清空vector,并存入sum
- 若若等于则将sum存入vector
- 若左侧数大于sum继续递归
- 若右侧数大于sum继续递归
四、时间复杂度分析
假定n=2^k,将递推式扩展:
T1(n)=2T(n/2)+1
=2*2T(n/4)+1+1
=2*2*2T(n/8)+1+1+1
......
=2^k*T(1)+n
=2n
时间复杂度为T(n)=T1(n)+T2(n)=O(nlogn)
五、流程图
六、实验步骤和调试过程
1. 测试数据及结果分析
测试数据规模为:
规模 | 1000000 | 2000000 | 3000000 | 4000000 | 5000000 | 6000000 | 7000000 | 8000000 | 9000000 |
时间(ms) | 244 | 502 | 824 | 1023 | 1258 | 1503 | 1876 | 2058 | 2257 |
散点图如下:
七、代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> z;
int maxsum = -1;
void findMode(int number[], int left, int right) {
if (left >= right) {
return;
}
int mid = (left + right) / 2;
int count = 1;
for (int i = mid + 1; i <= right && number[mid] == number[i]; ++i) {
count++;
}
for (int j = mid - 1; j >= left && number[mid] == number[j]; --j) {
count++;
}
if (count > maxsum) {
z.clear();
maxsum = count;
z.push_back(number[mid]);
} else if (count == maxsum) {
z.push_back(number[mid]);
}
if (maxsum <= mid - left) {
findMode(number, left, mid - 1);
}
if (maxsum <= right - mid) {
findMode(number, mid + 1, right);
}
}