合并排序的递归与非递归写法

作业题:

(1)采用递归合并排序算法,根据基站k-dist距离,对基站从小到大进行排序,观察、统计递归层次。

(2)采用非递归合并排序算法,根据基站k-dist距离,对基站从小到大进行排序


合并排序基本思想:将待排序元素分成大小大致相同的2个子集合,分别对2个子集合进行排序; 将排好序的子集合合并成为所要求的排好序的集合。 

递归:

#include<iostream>
#include<string>
#include<fstream>
#define max 2000
using namespace std;

typedef struct Basestation
{
	int ENODEBID;
	float LONGITUDE;//经度 
	float LATITUDE;//纬度 
	float K_DIST ;
 }Basestation;
 
Basestation a[max], b[max];

void MergeSort(int left, int right);
void Merge(int left, int mid, int right);
 
int main()
{
	int i = 1;
	int num = 0;
	ifstream file;
	file.open("Data_Of_Basestation.txt", ios::in);
	if(file.bad())
	{
		cout<<"打开文件时发生错误"<<endl;
		return 0;
	}
	while(!file.eof())
	{
		file>>a[i].ENODEBID>>a[i].LONGITUDE>>a[i].LATITUDE>>a[i].K_DIST;
		i++;
		num++;
		//cout<<a[i].ENODEBID<<" "<<a[i].LONGITUDE<<" "<<a[i].LATITUDE<<" "<<a[i].K_DIST<<endl;
		file.get();
		if(file.peek()==EOF)
			break;
	}
	MergeSort(1, num);
	cout<<"排序结果:"<<endl;
	cout<<" 基站编号 "<<"\t"<<" 基站经度 "<<"\t"<<" 基站纬度 "<<"\t"<<" K_DIST "<<endl; 
	for(int j=1; j<=num; j++)
	{
		cout<<a[j].ENODEBID<<"\t"<<a[j].LONGITUDE<<"\t"<<a[j].LATITUDE<<"\t"<<a[j].K_DIST<<endl;
	}
	file.close();
	return 0;
 } 
 
void MergeSort(int left, int right)
{
	if(left<right)
	{
		int mid;
		mid = (left + right) / 2;
		MergeSort(left, mid);//左半部排序
		MergeSort(mid+1, right);//右半部排序
		Merge(left, mid, right);//左右合并排序 
	}
 } 
 
void Merge(int left, int mid, int right)//两个子段序列的合并操作 
{
	int i = left;
	int j = mid+1;
	int k = left;
	while(i<=mid && j<=right)
	{
		if(a[i].K_DIST<=a[j].K_DIST)
			b[k++] = a[i++];
		else
			b[k++] = a[j++];
	}
	if(i>mid)
	{
		for(int q=j; q<=right; q++)
			b[k++] = a[q];
	}
	else
	{
		for(int q=i; q<=mid; q++)
			b[k++] = a[q];
	}
	for(int h=left; h<=right; h++)//将左右合并在b中排序完成的序列复制到a数组 
	{	
		a[h] = b[h];
	}
}

非递归写法:将数组划分为隔s的一个个小片段,对每个小片段进行排序,s增加后对应数组片段边长,对每个片段进行排序意味为对更低级的两个片段进行合并

#include<iostream>
#include<string>
#include<fstream>
#define max 2000
using namespace std;

typedef struct Basestation
{
	int ENODEBID;
	float LONGITUDE;//经度 
	float LATITUDE;//纬度 
	float K_DIST ;
 }Basestation;
 
Basestation a[max], b[max];

void MergeSort(Basestation a[], int n);
void MergePass(Basestation x[], Basestation y[], int s, int n);
void Merge(Basestation x[], Basestation y[], int left, int mid, int right);

int main()
{
	int i = 1;
	int num = 0;
	ifstream file;
	file.open("Data_Of_Basestation.txt", ios::in);
	if(file.bad())
	{
		cout<<"打开文件时发生错误"<<endl;
		return 0;
	}
	while(!file.eof())
	{
		file>>a[i].ENODEBID>>a[i].LONGITUDE>>a[i].LATITUDE>>a[i].K_DIST;
		i++;
		num++;
		//cout<<a[i].ENODEBID<<" "<<a[i].LONGITUDE<<" "<<a[i].LATITUDE<<" "<<a[i].K_DIST<<endl;
		file.get();
		if(file.peek()==EOF)
			break;
	}
	MergeSort(a, num);
	cout<<"排序结果:"<<endl;
	cout<<" 基站编号 "<<"\t"<<" 基站经度 "<<"\t"<<" 基站纬度 "<<"\t"<<" K_DIST "<<endl; 
	for(int j=1; j<=num; j++)
	{
		cout<<a[j].ENODEBID<<"\t"<<a[j].LONGITUDE<<"\t"<<a[j].LATITUDE<<"\t"<<a[j].K_DIST<<endl;
	}
	file.close();
	return 0;
 } 
 
void MergeSort(Basestation a[], int n)
{
	int s = 1;
	while(s<n)
	{
		MergePass(a, b, s, n);
		s+=s;
		MergePass(b,a,s,n);
		s+=s;
	}
}

void MergePass(Basestation x[], Basestation y[], int s, int n)
{
	int i=0;
	while(i<=n-2*s)
	{
		Merge(x, y, i, i+s-1, i+2*s-1);
		i+=2*s;
	}
	if(i+s<=n)
		Merge(x, y, i, i+s-1, n);
	else
		for(int j=i; j<=n; j++)
			y[j] = x[j];
}

void Merge(Basestation a[], Basestation b[], int left, int mid, int right)//两个子段序列的合并操作 
{
	int i = left;
	int j = mid+1;
	int k = left;
	while(i<=mid && j<=right)
	{
		if(a[i].K_DIST<=a[j].K_DIST)
			b[k++] = a[i++];
		else
			b[k++] = a[j++];
	}
	if(i>mid)
	{
		for(int q=j; q<=right; q++)
			b[k++] = a[q];
	}
	else
	{
		for(int q=i; q<=mid; q++)
			b[k++] = a[q];
	}
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值