用x轴上某个点m将s划分成两个集合使得s1的元素都比m小,s2的元素都比m大,这样对于所有 p q有p<q
递归的在s1 s2上找出其最近点对|p1 p2| |q1 q2| p3是s1中最大的 q3是s2中最小的
s中最近点对或者是{p1,p2}或者是{q1,q2}或者是某个{p3,q3}
#include<iostream>
#include<Windows.h>
#include<time.h>
#include<assert.h>
#include<vector>
#include<stdlib.h>
#include<algorithm>
using namespace std;
template<class Type>
int RandPartition(Type *ar,int left,int right)
{
Sleep(300);
srand(time(NULL));
int pos=(rand()%(right-left+1))+left;
swap(ar[pos],ar[left]);
return Partition(ar,left,right);
}
template<class Type>
int Partition(Type *ar,int left,int right)
{
Type tmp=ar[left];
int i=left,j=right;
while(i<j)
{
while(i<j&&ar[j]>=tmp) --j;
if(i<j)
{
ar[i]=ar[j];
}
while(i<j&&ar[i]<=tmp) ++i;
if(i<j)
{
ar[j]=ar[i];
}
}
ar[i]=tmp;
return i;
}
template<class Type>
Type SelectK_Min(Type *ar,int n,int k)
{
assert(ar!=NULL&&n>0&&k>=1&&k<=n);
return SelectK(ar,0,n-1,k);
}
int MaxS(int *br,int left,int right)
{
int max=br[left];
for(int i=left+1;i<right;++i)
{
if(max<br[i])
{
max=br[i];
}
}
return max;
}
int MinS(int *br,int left,int right)
{
int min=br[left];
for(int i=left+1;i<=right;++i)
{
if(min>br[i])
{
min=br[i];
}
}
return min;
}
int Min(int d1,int d2,int d3)
{
return (std::min)(d1,(std::min)(d2,d3));
}
template<class Type>
Type SelectK(Type *ar,int left,int right,int k)//划分函数 k表示第几小 k是相对下标 (right-left+1)/2
//right left使用的是绝对下标
{
if(left==right&&k==1)
return ar[left];
int index=RandPartition(ar,left,right);
int pos=index-left+1;
if(k<=pos)
return SelectK(ar,left,index,k);
else return SelectK(ar,index+1,right,k-pos);
}
int Spair(int *br,int left,int right)//left right是下标
{
if(right-left<=0)//此区域只有一个元素
{
return INT_MAX;
}
int k=(right-left+1)/2;
SelectK(br,left,right,k);
int pos=left+k-1;
//S1 S2区域
int d1=Spair(br,left,pos);//找S1区域里最小的距离
int d2=Spair(br,pos+1,right);//找S2区域里最小的距离
int maxs1=MaxS(br,left,pos);//S1里的最大值
int mins2=MinS(br,pos+1,right);//s2里的最小值
return Min(d1,d2,mins2-maxs1);//找最小值
}
int Spair(int *br,int n)
{
if(NULL==br||n<2)
return INT_MAX;
else
return Spair(br,0,n-1);
}
int main()
{
int ar[]={56,34,89,78,45,12,23,67,90,100};
int n=sizeof(ar)/sizeof(ar[0]);//n代表数据规模
int mind=Spair(ar,n);//找最小距离
cout<<mind<<endl;
return 0;
}