1、问题:
设L是n个元素的集合,从L中选取第k小的元素,其中1<=k<=n。
这里第k小的元素是指,当L按从小到大排好序之后,排在第k个位置的元素。
利用特定分治策略选出第k小的元素。
2、解析:
3、设计(核心伪代码):
void Closest_Pair(int left, int right, int flag) { //最近点对距离 先对x排序,flag表示禁用的点
if(left == right) return ; //只剩1个点
if(left + 1 == right){
if(P[left].id != flag && P[right].id != flag){
if(dis > Dist(P[left], P[right])){
dis = Dist(P[left], P[right]);
if(flag == -1){
pos[0] = P[left].id;
pos[1] = P[right].id;
}
}
}
return ;
}
int mid = (left + right) / 2; //分治
Closest_Pair(left, mid, flag); // 求s1(集合)中的最近点对
Closest_Pair(mid + 1, right, flag); //求s2中的最近点对
int k = 0;
for(int i = left; i <= right; i++){ //在s1和s2中间附近找可能的最近点对
if(abs(P[mid].x - P[i].x) <= dis && P[i].id != flag) //按x坐标来找
tmp_P[k++] = P[i];
}
sort(tmp_P, tmp_P + k, cmpy); //对y排序 用于剪枝
for(int i = 0; i < k; i++){
for(int j = i + 1; j < k && tmp_P[j].y - tmp_P[i].y < dis; j++){
if(dis > Dist(tmp_P[i], tmp_P[j])){
if(flag == -1){
pos[0] = tmp_P[i].id;
pos[1] = tmp_P[j].id;
}
dis = Dist(tmp_P[i], tmp_P[j]);
}
}
}
}
4、分析:
时间复杂度为 O ( n ) O(n) O(n)