最近点对问题
找出平面上一对距离最短的点,时间复杂度 O(nlgn)
using System;
using System.Collections.Generic;namespace dataLearn
{struct Coordinate{public float x;public float y;public Coordinate(float x,float y){this.x = x;this.y = y;}public override string ToString(){return $"x:{x},y:{y}";}public void print(){Console.Out.WriteLine(this);}}class Program{static void Main(string[] args){List<Coordinate> coordinates = new List<Coordinate> { new Coordinate(1,2),new Coordinate(1,6),new Coordinate(2,4),new Coordinate(2,8),new Coordinate(3,1),new Coordinate(3,6),new Coordinate(3,10),new Coordinate(4,3),new Coordinate(5,1),new Coordinate(5,5),new Coordinate(5,9),new Coordinate(6,7),new Coordinate(7,1),new Coordinate(7,4),new Coordinate(7,9),new Coordinate(8,6)};coordinates.Sort((x, y) =>{if (x.x == y.x) return 0;else if (x.x > y.x) return 1;else return -1;});var co = getShortestDistance(coordinates, 0, coordinates.Count - 1);co.Item1.print();co.Item2.print();Console.Out.Write(" distance "+co.d);}static float getDistance(Coordinate x, Coordinate y){return (float)Math.Sqrt((x.x - y.x) * (x.x - y.x) + (x.y - y.y) * (x.y - y.y));}static (Coordinate, Coordinate, float d) getShortestDistance(List<Coordinate> coordinates, int start, int end){int length = end - start + 1;if (length > 3){int middle = (start + end) / 2;var dl = getShortestDistance(coordinates, start, middle);var dr = getShortestDistance(coordinates, middle + 1, end);float d = Math.Min(dl.d, dr.d);float left = coordinates[middle].x - d;float right = coordinates[middle].x + d;int child_start = 0;int child_end = 0;for (int i = start; i < end+1; i++){if (child_start == 0 && coordinates[i].x >= left){child_start = i;}else if (coordinates[i].x <= right){child_end = i;}elsebreak;}List<Coordinate> temp = new List<Coordinate>();for (int i = child_start; i <= child_end; i++){temp.Add(coordinates[i]);}temp.Sort((x,y)=>{if (x.y == y.y) return 0;else if (x.y > y.y) return 1;else return -1;});float dmin = d;int c1 = 0, c2 = 0;for(int i= 0;i<temp.Count-1;i++){for (int j=i+1;j<temp.Count;j++){if (temp[i].y + d < temp[j].y){break;}else if (getDistance(temp[i], temp[j]) < dmin){dmin = getDistance(temp[i], temp[j]);c1 = i;c2 = j;}}}if (dmin < d){return (temp[c1], temp[c2], dmin);}else return dl.d <= dr.d ? dl : dr;}else if (length == 3){float d12 = getDistance(coordinates[start], coordinates[start + 1]);float d23 = getDistance(coordinates[start + 1], coordinates[start + 2]);float d13 = getDistance(coordinates[start], coordinates[start + 2]);if (d12 <= d23 && d12 <= d13){return (coordinates[start], coordinates[start + 1], d12);}else if (d23 <= d12 && d23 <= d13){return (coordinates[start + 1], coordinates[start + 2], d23);}else{return (coordinates[start], coordinates[start + 2], d13);}}else{return (coordinates[start], coordinates[end], getDistance(coordinates[start], coordinates[end]));}}}
}