/// <summary> /// 将节点按距离插入列表中 /// </summary> /// <param name="list"></param> /// <param name="k"></param> /// <param name="bbf"></param> private void insert(List <BBFData> list, int k, BBFData bbf) { if (list.Count == 0) { list.Add(bbf); return; } int ret = 0; int oldCount = list.Count; var last = list[list.Count - 1]; var df = bbf.d; var dn = last.d; if (df >= dn) // bbf will be appended to list { if (oldCount == k) // already has k nearest neighbors, nothing should be done { return; } list.Add(bbf); // append directively return; } // bbf will be inserted into list internally if (oldCount < k) { // suppose bbf be inserted at idx1, all elements after idx1 should be moved 1 backward respectively // first we move the last element list.Add(last); } // from backer to former, move related elements int i = oldCount - 2; while (i > -1) { if (list[i].d <= df) { break; } list[i + 1] = list[i]; // move backward i--; } i++; list[i] = bbf; }
/// <summary> /// 搜索k近邻点 /// </summary> /// <param name="p"></param> /// <param name="k"></param> /// <returns></returns> public List <TreeNode> BBFSearchKNearest(Point p, int k) { var list = new List <BBFData>(); // var pq = new MinPQ(); pq.insert(new PQNode(root, 0)); int t = 0; while (pq.nodes.Count > 0 && t < max_nn_chks) { var expl = pq.pop_min_default().data; expl = Explore2Leaf(expl, p, pq); var bbf = new BBFData(expl, expl.point.Distance(p)); insert(list, k, bbf); t++; } return(list.Select(l => l.data).ToList()); }