快速排序及其改进

来源:互联网 发布:景区历年游客数据统计 编辑:程序博客网 时间:2024/05/22 10:35
快速排序原理:对输入的待排序(子)数组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 2000using 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]<=xif(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);}




0 0