k近邻算法C++二维实现
这是一个k近邻算法的二维实现(即K=2的情况)。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <cmath> using namespace std; const double inf = 1000.0; const int maxn = 10010;void debug_dfs(int); void go_method(); bool should_go(int); void dfs(int); void back_method();double Left[maxn], Right[maxn], Top[maxn], Button[maxn]; int tree[maxn][2], parent[maxn], cnt = 0, n; int depth[maxn]; struct point {double x, y; }; vector<point> points[maxn]; queue<int> q; point tmp[maxn]; point node[maxn]; point p0, anspoint; int ansid; double R; bool cmpx(point a, point b) {return a.x < b.x; } bool cmpy(point a, point b) {return a.y < b.y; } int main() {scanf("%d", &n);point p;for(int i=0;i<n;i++) {scanf("%lf%lf", &p.x , &p.y);points[cnt].push_back(p);}depth[cnt] = 0;Left[cnt] = Button[cnt] = -inf;Right[cnt] = Top[cnt] = inf;parent[cnt] = -1;q.push(cnt);while(!q.empty()) {int u = q.front();q.pop();vector<point> &ps = points[u];int sz = ps.size();if(sz <= 0) continue;if(sz == 1) {node[u] = ps[0];continue;}for(int i=0;i<sz;i++) {tmp[i] = ps[i];}if(depth[u] % 2 == 0) sort(tmp, tmp+sz, cmpx);else sort(tmp, tmp+sz, cmpy);int mid = sz / 2;node[u] = tmp[mid];int lsz = mid, rsz = sz - 1 - mid;if(lsz) {int l = ++cnt;tree[u][0] = l;parent[l] = u;depth[l] = depth[u] + 1;q.push(l);for(int i=0;i<mid;i++) points[l].push_back(tmp[i]);Left[l] = Left[u]; Right[l] = Right[u]; Top[l] = Top[u]; Button[l] = Button[u];if(depth[u] % 2 == 0) Right[l] = tmp[mid].x;else Top[l] = tmp[mid].y;}if(rsz) {int r = ++cnt;tree[u][1] = r;parent[r] = u;depth[r] = depth[u] + 1;q.push(r);for(int i=mid+1;i<sz;i++) points[r].push_back(tmp[i]);Left[r] = Left[u]; Right[r] = Right[u]; Top[r] = Top[u]; Button[r] = Button[u];if(depth[u] % 2 == 0) Left[r] = tmp[mid].x;else Button[r] = tmp[mid].y;}}scanf("%lf%lf", &p0.x, &p0.y);back_method();printf("(%.2lf,%.2lf)\n", node[ansid].x, node[ansid].y);//debug_dfs(0);return 0; }void go_method() {int cur = 0;ansid = cur;while(true) {int l = tree[cur][0], r = tree[cur][1];if(l && Left[l] <= p0.x && Right[l] >= p0.x && Button[l] <= p0.y && Top[l] >= p0.y) {cur = l;ansid = l;} else if(r && Left[r] <= p0.x && Right[r] >= p0.x && Button[r] <= p0.y && Top[r] >= p0.y) {cur = r;ansid = r;} else {R = sqrt((p0.x-node[ansid].x)*(p0.x-node[ansid].x)+(p0.y-node[ansid].y)*(p0.y-node[ansid].y));return;}} }bool should_go(int u) {double dd, tt;dd = fabs(p0.x - Left[u]);if(dd < R) {tt = sqrt(R*R-dd*dd);if(p0.y-tt > Button[u] && p0.y-tt < Top[u]) return true;if(p0.y+tt > Button[u] && p0.y+tt < Top[u]) return true;if(Button[u] > p0.y-tt && Button[u] < p0.y+tt) return true;if(Top[u] > p0.y-tt && Top[u] < p0.y+tt) return true;}dd = fabs(p0.x - Right[u]);if(dd < R) {tt = sqrt(R*R-dd*dd);if(p0.y-tt > Button[u] && p0.y-tt < Top[u]) return true;if(p0.y+tt > Button[u] && p0.y+tt < Top[u]) return true;if(Button[u] > p0.y-tt && Button[u] < p0.y+tt) return true;if(Top[u] > p0.y-tt && Top[u] < p0.y+tt) return true;}dd = fabs(p0.y - Button[u]);if(dd < R) {tt = sqrt(R*R-dd*dd);if(p0.x-tt > Left[u] && p0.x+tt < Right[u]) return true;if(p0.x+tt > Left[u] && p0.x+tt < Right[u]) return true;if(Left[u] > p0.x-tt && Left[u] < p0.x+tt) return true;if(Right[u] > p0.x-tt && Right[u] < p0.x+tt) return true;}dd = fabs(p0.y - Top[u]);if(dd < R) {tt = sqrt(R*R-dd*dd);if(p0.x-tt > Left[u] && p0.x+tt < Right[u]) return true;if(p0.x+tt > Left[u] && p0.x+tt < Right[u]) return true;if(Left[u] > p0.x-tt && Left[u] < p0.x+tt) return true;if(Right[u] > p0.x-tt && Right[u] < p0.x+tt) return true;}return false; }void dfs(int u) {double _x = node[u].x, _y = node[u].y;double _r = sqrt((_x-p0.x)*(_x-p0.x)+(_y-p0.y)*(_y-p0.y));if(_r < R) {R = _r;ansid = u;}int l = tree[u][0], r = tree[u][1];if(l && should_go(l)) dfs(l);if(r && should_go(r)) dfs(r);return; }void back_method() {go_method();int cur = ansid, precur;while(cur != 0) {precur = cur;cur = parent[cur];int l = tree[cur][0], r = tree[cur][1];if(precur == l && r && should_go(r)) dfs(r);else if(precur == r && l && should_go(l)) dfs(l);} }void debug_dfs(int u) {printf("dep[%d] = %d; (%.2lf,%.2lf); left:%.2lf,right:%.2lf,button:%.2lf,top:%.2lf\n",u, depth[u], node[u].x , node[u].y, Left[u], Right[u], Button[u], Top[u]);int l = tree[u][0], r = tree[u][1];if(l) debug_dfs(l);if(r) debug_dfs(r); }