快速排序

快速排序(面试版)

快速排序是由冒泡排序改进而得的。在冒泡排序中,只对相邻的两个记录进行比较,因此每次交换两个相邻记录时只能消除一个逆序。而快速排序可以通过两个不相邻记录的一次交换,来消除多个逆序,会大大加快排序的速度。

快速排序基本思想

1、先从数列中取出一个数作为基准数。

2、分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。

3、再对左右区间(重新选择中心元素)重复第二步,直到各区间只有一个数。

快速排序基本步骤
在这里插入图片描述
举例
在这里插入图片描述
代码实现

int Partition(SqList &L,int low,int high)
{//对顺序表L中的子表r[low..high]进行一趟排序,返回枢轴位置
    L.r[0] = L.r[low]//用子表的第一个记录做枢轴记录 
    pivotkey = L.r[low].key;//枢轴记录关键字保存在pivotkey中
    while(low<high)  //从表两端交替地向中间扫描
    {
       while(low<high && L.r[high].key>=pivotkey)  --high;
       L.r[low] = L.r[high];  //将比枢轴记录小的记录移到低端 
       while(low<high && L.r[low].key<=pivotkey)  ++low;
       L.r[high] = L.r[low];  //将比枢轴记录大的记录移到高端 
    }
	L.r[low] = L.r[0];//将枢轴记录放到此时low=high的位置 ,也可以写成	L.r[high] = L.r[0];
	return low;       // return high也可以 
}

void QSort(SqList &L,int low,int high)
{//调用前置初值:low=1;high=L.length;
//对顺序表L中的子序列L.r[low..high]快速排序 
	if(low<high)    //长度大于一
	{
		pivotloc = Partition(L,low,high); 
		//将L.r[low..high]一分为二,pivotloc为枢轴元素
		Qsort(L,low,pivotloc-1);//对左子表递归排序 
		Qsort(L,pivotloc+1,high);//对右子表递归排序 
	}
 } 
 
 void QuickSort(SqList &L)
 {
 	QSort(L,1,L.length); //对顺序表L的1~L.length(所有的元素)个元素进行排序 
 }

算法分析

(1)时间复杂度
从快速排序算法的递归树可知,快速排序的趟数取决于递归树的深度。平均情况下,快速排序的时间复杂度是O(nolg2n).

(2)空间复杂度
最好情况下的空间复杂度是O(log2n)
最坏情况下为O(n)
算法特点

  1. 记录非顺次的移动导致排序方法是不稳定的
  2. 排序过程需要定位表的下界和上界,所以适合用于顺序结构,很难用于链式结构
  3. 当n较大时,在平均情况下快速排序是所有内部排序方法中速度最快的一种,所以其适合初始记录无序、n较大时的情况

快速排序 C++sort函数

1 sort 函数头文件

#include<algorithm>

2 Sort函数有三个参数:
sort(begin,end,cmp)
(1)第一个是要排序的数组的起始地址。(begin)
(2)第二个是结束的地址(最后一位要排序的地址的下一地址,对于一个vector来说是a.end())(end)
(3)第三个参数是排序的方法,可以是从大到小也可是从小到大,还可以不写第三个参数,此时默认的排序方法是从小到大排序。(cmp)

3 cmp参数不写默认升序

cmp 函数中return a<b 默认降序

#include<iostream>
#include<algorithm>
using namespace std;

bool cmp(int a,int b)
{
	return a<b;  //降序
}
int main()
{
   int a[n];
   sort(a,a+n);
   ....
   return 0;
   }

cmp函数中return a>b 默认升序

#include<iostream>
#include<algorithm>
using namespace std;

bool cmp(int a,int b)
{
	return a>b;    //升序
}
int main()
{
   int a[n];
   sort(a,a+n);
   ....
   return 0;
   }

4. 其实排序完全可以不用自己写cmp函数就可以实现排序

升序:sort(begin,end,less());
降序:sort(begin,end,greater());

5. 利用sort函数对数组排序

#include<iostream>
#include<algorithm>  //调用sort函数
using namespace std;
 
bool com(int a, int b)  
{
    return a > b;//从大到小排序
}
 
int main(){
    int a[10] = {9,6,3,8,5,2,7,4,1,0};
    for(int i = 0; i < 10; i++)
    sort(a, a+10, cmp); //在这里就不需要对cmp函数传入参数了,这是规则
    for(int i = 0; i < 10; i++)
        cout << a[i] << " ";
    cout << endl;
    return 0;
}

6 利用sort 对字符排序
使用迭代器

#include<iostream>
#include<algorithm>
using namespace std;

int main()
{
	string a="hello world";
	sort(a.begin(),a.end());
	cout<<a;  //运行结果 空格dehllloorw
	return 0; 
}

7 利用sort 对字符串排序

#include<iostream>
#include<algorithm>
using namespace std;

int main()
{
	string a[5];
	for(int i=0;i<5;i++)
	cin>>a[i];
	
	sort(a,a+5);
	
	cout<<endl;
	for(int i=0;i<5;i++)
	cout<<a[i]<<endl;
	return 0;
}

8 利用sort对结构体排序
例题 生日
题目描述:
cjf君想调查学校OI组每个同学的生日,并按照从大到小的顺序排序。但cjf君最近作业很多,没有时间,所以请你帮她排序。
输入格式

有2行,
第1行为OI组总人数n;
第2行至第n+1行分别是每人的姓名s、出生年y、月m、日d。

输出格式

有n行,即n个生日从大到小同学的姓名。(如果有两个同学生日相同,输入靠后的同学先输出)

输入样例:

3
Yangchu 1992 4 23
Qiujingya 1993 10 13
Luowen 1991 8 1

输出样例:

Luowen
Yangchu
Qiujingya

代码:

#include<iostream>
#include<algorithm> 
using namespace std;

struct student
{
	string name;
	int y,m,d;
	int shu;
}stu[105];
bool cmp(student a,student b)
{
	if(a.y!=b.y)  return a.y<b.y;
	if(a.m!=b.m)  return a.m<b.m;
	if(a.d!=b.d)  return a.d<b.d;
	return a.shu>b.shu;
}
int main()
{
	int n;
	cin>>n;
	
	for(int i=0;i<n;i++)
	{
		cin>>stu[i].name >>stu[i].y >>stu[i].m >>stu[i].d;
		stu[i].shu =i;
	}
	sort(stu,stu+n,cmp);//对结构体排序
	for(int i=0;i<n;i++)  cout<<stu[i].name <<endl;
	
	
	
	return 0;
 } 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值