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);
}