算法学习笔记5——分治法求解最近对问题并测算算法运行时间

完整代码:

#include<iostream>
#include<time.h> 
#include<stdlib.h>
#include<math.h>
#include <stdio.h>
#include <windows.h>
#include<iomanip>
using namespace std;
struct point
{
	int x, y;
};

void Initial(int N, point* p) 
{    
	srand(time(0));  //种子为数据的规模  
    int i;    
    for (i = 0; i < N; i++) {  
//产生随机数,X集和Y集中点的内容是一样的,只是排序的方法不同而已        
        p[i].x = rand()%(10-1)+1;        
        p [i].y = rand()%(10-1)+1;    
		cout<<"("<<p[i].x<<","<<p[i].y<<")"<<endl;    
	}
}

double Distance(point a, point b)
{
	return sqrt(double((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)));
}

int Partitionx(point r[ ], int first, int end)          //划分
{	
    int i = first, j=end;//初始化待划分区间
    while (i < j)	
    {  
        while (i < j && r[i].x <= r[j].x) j--;          //右侧扫描
        if (i < j) { 
			point temp = r[i]; r[i] = r[j]; r[j] = temp;     //将较小记录交换到前面
			i++; 
	  	}
      	while (i < j && r[i].x <= r[j].x) i++;         //左侧扫描
      	if (i < j) {
			point temp = r[i]; r[i] = r[j]; r[j] = temp;     //将较大记录交换到后面
        	j--; 
	  	}
   }
   return i;// 返回轴值记录的位置
}

void QuickSortx(point r[ ], int first, int end)        //快速排序
{	
    int pivot;
    if (first < end) {      
 	    pivot = Partitionx(r, first, end);    //划分,pivot是轴值在序列中的位置
    	QuickSortx(r, first, pivot-1);      //求解子问题1,对左侧子序列进行快速排序
     	QuickSortx(r, pivot+1, end);      //求解子问题2,对右侧子序列进行快速排序
    }
}

int Partitiony(point r[ ], int first, int end)          //划分
{	
   int i = first, j=end;                       //初始化待划分区间
   while (i < j)	
   {  
      while (i < j && r[i].y <= r[j].y) j--;          //右侧扫描
      if (i < j) { 
		point temp = r[i]; r[i] = r[j]; r[j] = temp;     //将较小记录交换到前面
		i++; 
	  }
      while (i < j && r[i].y <= r[j].y) i++;         //左侧扫描
      if (i < j) {
		point temp = r[i]; r[i] = r[j]; r[j] = temp;     //将较大记录交换到后面
        j--; 
	  }
   }
   return i;                                // 返回轴值记录的位置
}

void QuickSorty(point r[ ], int first, int end)        //快速排序
{	
   int pivot;
   if (first < end) {      
     pivot = Partitiony(r, first, end);    //划分,pivot是轴值在序列中的位置
     QuickSorty(r, first, pivot-1);      //求解子问题1,对左侧子序列进行快速排序
     QuickSorty(r, pivot+1, end);      //求解子问题2,对右侧子序列进行快速排序
   }
}
//全局变量
double dd=100000;
point K,L; 
double Closest_DC(point S[ ], int low, int high)
{

    QuickSortx(S, 0, high);
	double d1, d2, d3, d;
	int mid, i, j, index;
	point P[high-low+1];                   //存放P1和P2
	if (high - low == 1)
	{	
		d=Distance(S[low], S[high]);	
		if(d<dd){	K=S[low];L=S[high];	dd=d;}
		return d;
	}
	if (high - low == 2)
	{
		d1 = Distance(S[low], S[low+1]);
	    d2 = Distance(S[low+1], S[high]);
		d3 = Distance(S[low], S[high]);
		if ((d1 < d2) && (d1 < d3))
		{
			if(d1<dd){	
				K=S[low],L=S[low+1];dd=d1;	
			}
			return d1;	
		}else if (d2 < d3){
		    if(d2<dd){	
				K=S[low+1],L=S[high];dd=d2;
			}
		    return d2;			
		}else{
			if(d3<dd){	
			 	K=S[low],L=S[high];dd=d3;	
			}
			return d3;	
		}
	}
	mid = (low + high)/2;
	d1 = Closest_DC(S, low, mid);
	d2 = Closest_DC(S, mid+1, high);
	if(d1<=d2) 
	{	
		d = d1;	
		if(d1<dd){	K=S[low];L=S[mid];	dd=d; }	
	}
	else 
	{	
		d = d2;	
		if(d2<dd){	K=S[mid+1];L=S[high];dd=d;	}		
	}
    index = 0;
	for (i = mid; (i >= low) && (S[mid].x - S[i].x < d); i--)
		P[index++] = S[i];
	for (i = mid + 1; (i <= high) && (S[i].x - S[mid].x < d); i++)
		P[index++] = S[i];
	QuickSorty(P, 0, index-1);
	for (i = 0; i < index; i++)
	{
		for(j = i + 1; j < index; j++)
		{
			if (P[j].y - P[i].y >= d) 
				break;
			else
			{
				d3 = Distance(P[i], P[j]);
				if (d3 < d)
				{	
					d = d3;
					if (d3 < dd){ K=P[i];L=P[j];	dd=d; }
				}
			}
		}
	}
	return d;
}

int main(){
	LARGE_INTEGER nFreq;
    LARGE_INTEGER nBeginTime;
    LARGE_INTEGER nEndTime;
    double time;
	
	point S[20];
	cout<<"输入点的个数为12"<<endl; 
	Initial(12,S);
	Closest_DC(S,0,12);
	cout<<"两个坐标分别是:"<< "("<<K.x<<","<<K.y<<")"<< "("<<L.x<<","<<L.y<<")"<<endl; 
	cout<<"分治法求解最近距离为:"<<dd<<endl;
	
	QueryPerformanceFrequency(&nFreq);
 	QueryPerformanceCounter(&nBeginTime); 
    for (int i = 0; i < 1000; i++)
	{
		i++;
	}
    QueryPerformanceCounter(&nEndTime);
    time=(double)(nEndTime.QuadPart-nBeginTime.QuadPart)*1000000000/(double)(nFreq.QuadPart);
    cout<<"程序运行时间为:"<<time; //单位是纳秒. 

	return 0;
}

运行结果:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值