private void btnTinh5_Click(object sender, EventArgs e)
        {
            try
            {
                Stopwatch time = new Stopwatch();
                string input = txtInput5.Text;
                string[] coordinates = input.Split(' ');
                n=coordinates.Length-1;
                diem = new diem[n];
                int i = 0;
                time.Start();
                foreach (string s in coordinates)
                {
                    if (i >= n)
                    {
                        break;
                    }
                    string[] coord = s.Split(',');
                    diem[i++] = new diem(int.Parse(coord[0]), int.Parse(coord[1]));
                    //i++;

                }
                closestpair closest = new closestpair();
                float d = closest.ClosestPair(diem, i);

                time.Stop();
                txtKetQua5.Text = d.ToString();
                textBox1.Text = time.Elapsed.Milliseconds.ToString();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
 public float BruteForce(diem[] a, int n)
 {
     float d = float.MaxValue;
     for (int i = 0; i < n - 1; i++)
     {
         for (int j = i + 1; j < n; j++)
         {
             if (KhoangCach(a[i], a[j]) < d)
             {
                 d = KhoangCach(a[i], a[j]);
             }
         }
     }
     return d;
 }
 public static float KhoangCach(diem diem1, diem diem2)
 {
     return (float)Math.Sqrt((diem1.x - diem2.x) * (diem1.x - diem2.x) + (diem1.y - diem2.y) * (diem1.y - diem2.y));
 }
 private bool IfExist(diem b,int vt)
 {
     for (int i = 0; i < vt; i++)
     {
         if (diem[i].x == b.x && diem[i].y == b.y)
         {
             return true;
         }
     }
     return false;
 }
        private void button7_Click(object sender, EventArgs e)
        {
            if (String.IsNullOrEmpty(txtNhap5.Text))
            {
                MessageBox.Show("Vui lòng nhập n");
                return;
            }
            //tạo bộ test ngẫu nhiên
            txtInput5.Text = "";
            n = int.Parse(txtNhap5.Text);

            diem = new diem[n];
            Random rand = new Random();
            for (int i = 0; i < n; i++)
            {
                diem[i] = new diem(rand.Next(n), rand.Next(n));
                if (IfExist(diem[i], i))
                {
                    continue;
                }
                txtInput5.Text += diem[i].ToString() + " ";
            }
        }
        private void mergeY(diem[] result, diem[] left, diem[] right)
        {
            int i1 = 0;   // index into left array
            int i2 = 0;   // index into right array

            for (int i = 0; i < result.Length; i++)
            {
                if (i2 >= right.Length || (i1 < left.Length && left[i1].y <= right[i2].y))
                {
                    result[i] = left[i1];    // take from left
                    i1++;
                }
                else
                {
                    result[i] = right[i2];   // take from right
                    i2++;
                }
            }
        }
 // Returns the second half of the given array.
 private diem[] rightHalf(diem[] a)
 {
     int size1 = a.Length / 2;
     int size2 = a.Length - size1;
     diem[] right = new diem[size2];
     for (int i = 0; i < size2; ++i)
     {
         right[i] = a[i + size1];
     }
     return right;
 }
        // Rearranges the elements of a into sorted order using
        // the merge sort algorithm (recursive).
        private void mergeSortY(diem[] a)
        {
            if (a.Length >= 2)
            {
                // split array into two halves
                diem[] left = leftHalf(a);
                diem[] right = rightHalf(a);

                // sort the two halves
                mergeSortY(left);
                mergeSortY(right);

                // merge the sorted halves into a sorted whole
                mergeY(a, left, right);
            }
        }
 private diem[] leftHalf(diem[] a)
 {
     int size1 = a.Length / 2;
     diem[] left = new diem[size1];
     for (int i = 0; i < size1; ++i)
     {
         left[i] = a[i];
     }
     return left;
 }
 private float KhoangCach(diem diem1, diem diem2)
 {
     return (float)Math.Sqrt((diem1.x - diem2.x) * (diem1.x - diem2.x) + (diem1.y - diem2.y) * (diem1.y - diem2.y));
 }
        private float Closest(diem[] p, diem[] q, int l, int r)
        {
            if ((r - l) <= 3)
            {
                return BruteForce(p, r - l);
            }
            else
            {
                int mid = l + (r-l) / 2;
                float dl = Closest(p, q, l, mid);
                float dr = Closest(p, q, mid + 1, r);
                float dmin = Math.Min(dl, dr);
                int num = 0;
                diem[] temp = new diem[r - l];
                float min = dmin * dmin;
                for (int k = l; k < r; k++)
                {
                    if (Math.Abs(q[k].x - p[mid].x) < dmin)
                    {
                        temp[num++] = q[k];
                    }
                }

                for (int i = 0; i < num - 1 ; i++)
                {
                    int j = i + 1;
                    while ((j < num ) && ((temp[j].y - temp[i].y) * (temp[j].y - temp[i].y) < min))
                    {
                        min = Math.Min(KhoangCach(temp[j], temp[i]) * KhoangCach(temp[j], temp[i]), min);
                        j++;
                    }
                }
                return (float)Math.Sqrt(min);
            }
        }
 public float ClosestPair(diem[] diem, int n)
 {
     mergeSortX(diem);
     diem[] p = diem;
     mergeSortY(diem);
     diem[] q = diem;
     float min = Closest(p, q, 0, n);
     return min;
 }