快速排序及其改进

本文介绍了一种改进的快速排序算法,并应用于基站的距离排序。通过引入随机化分区和递归层次记录,提高了排序效率和稳定性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

快速排序原理:对输入的待排序(子)数组a[p:r]

  step1.分解:按照一定规则,从中选择a[q],a[q]为基准元素,将划分为三段

          a[p:q-1],a[q], a[q+1, r],使得a[p:q-1]中的元素均小于等于a[q], a[q+1,r]中的 元素均大于a[q]

  step2. 递归求解:

              递归调用快速排序算法,对a[p:q-1]a[q+1,r]分别排序

  step3.合并:不需做任何计算,因为经上2步后,a[p:r]已经排好序


Partition原理:

Step1.挑选x=a[p],作为划分基准元素

Step2.使用指针i,从左向右搜索,找到不符合顺序要求的大元素a[i]>=x

   使用指针j,从右向左搜索,找到不符合顺序要求的小元素a[j]<=x

Step3. 交换大元素a[i]、小元素a[j],以保证左半段a[i]<x、右半段x<a[j];

Step4. 继续使用指针i、j,在剩余元素中搜索大元素、小元素,交换位置;
Step5. 使用指针i、j,继续搜索,直至搜索完整个数组元素,此时i>=j。

Step6.交换划分基准元素x=a[p]a[j],将序列分为满足顺序要求的3


改进快速排序注意点:

1、当a[p:r]已经排好序时,直接返回a[p:r],作为排序结果

2、为提高性能,修改Partition函数(固定选取a[p]为划分基准),改为RandomizedPartition:随机从a[p:r]中选取1个元素,作为划分基准元素,从而期望划分是对称的


原题:
n采用快速排序算法,根据基站k-dist距离,对基站从小到大进行排序。在排序主程序中设置全局变量,记录排序过程的递归层次。

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


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


int QuickSort(Basestation a[], int p, int r);
int Partition(Basestation a[], int p, int r);
int RandomizedPartition(Basestation a[], int p, int r);//增加随机划分元素的函数 
int Max(int a, int b)
{
	return (a>b)?a:b;
 } 
int Level;//关于递归层次的全局变量 


int main()
{
	int i = 1;
	int num = 0;
	srand((int)time(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;
	}
	Level = QuickSort(a, 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;
	}
	cout<<"递归层次"<<Level<<endl;
	file.close();
	return 0;
 } 
 
int QuickSort(Basestation a[], int p, int r)
{
	//判断是否满足非递减序列
	int i;
	int lev = 1;
	int lev1, lev2;
	for(i = p; i<r; i++)
	{
		if(a[i+1].K_DIST < a[i].K_DIST)
			break;
	 } 
	if(i == r)
		return 0;
	if(p<r)
	{
		int q = RandomizedPartition(a, p, r);
		lev1 = QuickSort(a, p, q-1);
		lev2 = QuickSort(a, q+1, r);
 		lev += Max(lev1, lev2);
	}
	return lev;
}


int Partition(Basestation a[], int p, int r)
{
	int i = p;
	int j = r+1;
	Basestation x = a[p];
	Basestation beitai;
	while(i<j)
	{
		while (a[++i].K_DIST <x.K_DIST && i<r);   //扩展左端a[p:i],左→右搜索大元素a[i]>=x
        while (a[--j].K_DIST >x.K_DIST);               //扩展右端a[j:r],左←右搜索小元素a[i]<=x
		if(i >= j)
		{
			break;
		}
		beitai = a[i];
		a[i] = a[j];
		a[j] = beitai;
	}
	a[p] = a[j];
	a[j] = x;
	return j; 
}


int RandomizedPartition(Basestation a[], int p, int r)//n随机从a[p:r]中选取1个元素,作为划分基准元素,从而期望划分是对称的
{
	int i;
	Basestation x;
	i = rand()%(r-p+1) + p;
	x = a[p];
	a[p] = a[i];
	a[i] = x;
	//cout<<p<<" "<<i<<" "<<r<<endl;
	return Partition(a, p, r);
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值