快 速 排 序

快速排序使用分而治之(divided and conpuer  即D&C)的策略。

快速排序的平均时间复杂度为O(nlogn),最差情形时间复杂度O(n2),额外空间为O(logn),是一个不稳定的算法。

快速排序是由冒泡排序改进而得的,它的基本思想是:在待排序的 n 个元素中任取一个元素(通常取第一个元素)作为基准,把该uansu放入适当的位置后 ,数据序列被次元素划分成两部分,所有关键字比该元素关键字小的元素放置在前一部分,所有关键字比该关键字元素大的元素放置在后一部分,并把该元素排在这两部分的中间(称该元素归位),这个过程称作一趟快速排序。之后对所有划分出来的两部分分别重复上述过程,直至每部分内只有一个元素或为空为止。

简而言之,每趟将表的第一个元素放入适当位置,将表一分为二,对子表按递归方式继续这种划分,直至划分的子表长为1或0。

一趟快速排序的划分过程是采用从两头向中间扫描的办法,同时交换与基准元素逆序的元素。

举个例子

设待排序的表有10个元素,其关键字为72,6,57,88,60,42,83,73,48,85,用快速排序方法进行排序的过程如下

第一次排序:

基准为6,左指针left指向基准后一个元素8,右指针right指向最后一个元素5

7265788604283734885

基准

 

左指针left       

右指针 right

72作为基准,即其他所有数据都和它做比较,小于它的放置在前半部分,大于它的放置在后半部分。此刻已经被取出,即代表72的存储空间可以填入其他数字。有些类似于“挖坑填数”。

基准72暂时取出,在排序过程中不会出现,只作为基准比较,只有最后一步的时候才将其插入进正确的位置。

由于右指针right为85>基准72,满足条件,所以right-1。

right-1后指向数据为48<基准72,所以需要改变数字的位置。right指针不变,等待下一个数字来填补这一个空位之后才能改变

7265788604283734885
48         
 left      

right

 

 

然后right指针保持不同,转而执行left指针。

由于left指针所指数据6<基准72,满足条件,所以left+1

left+1所指向数据57<基准72,满足条件,left+1

left+1所指向数据88>基准72,不满足条件,则改变位置。left指针不变,等待下一个数字来填补这个空位之后才能改变

4865788604283734885
        88 
 

 

 

left

   right  

right数据73>72,满足条件,right-1

right-1所指向数据83>72,满足条件,right-1

right-1所指向数据42<72,不满足条件,改变位置。right指针不变,等待下一个数字来填补这一个空位之后才能改变

4865788604283738885
   42      
    left

right

  

 

 

left数据60<72,满足条件,left+1

left+1后与right指针相等,停止程序,将基准72插入剩下的那个空位之中

4865742604283738885
     72    
  

 

  

right

    

整理可得

4865742607283738885

满足条件,前半部分都是比基准小的,后半部分都是比基准大的

然后再分别对绿色区域,和蓝色区域的数据进行快速排序,直至子表长为1或0停止,就使得有序了

第二次排序:

426485760

72

73838885

第三次排序:

642

48

5760

72

73

83

8588
#include<stdio.h>
#include<iostream>
using namespace std;
void quickSort(int *a,int s,int t){
    int l=s,r=t;   //左指针,右指针
	int x;   //基准
	if(s<t){     //区间里至少存在两个元素的情况
		x=a[l];    //区间的第一个元素作为基准
		while(l!=r){   //从区间两端交替向中间扫描,直至l>=r为止
		  while(r>l && a[r]>=x)
			  r--;   //从右向左扫描,找到第一个小于基准的值
		  a[l]=a[r];//交换
		  while(l<r && a[l]<=x)
			  l++;  //从左向右扫描,找到第一个大于基准的值
		  a[r]=a[l];//交换
		}
		a[l]=x;
		/*
		注意这里用的是s,t,因为l和r在排序过程中其值改变,
		并没有指向整个列表的第一个元素和最后一个元素
		*/
		quickSort(a,s,l-1);//对左区间递归排序
		quickSort(a,l+1,t);//对右区间递归排序
	}
}
int main(){
  int n;
  cout<<"输入要排序的数字个数:";
  cin>>n;
  int *a=new int(n);
  //初始化
  cout<<"输入要排序的数字:";
  for(int i=0;i<n;i++){
    cin>>a[i];
  }
  //调用快速排序
  quickSort(a,0,n-1);
  //显示排序后的数组
  cout<<"排序后:";
  for(int i=0;i<n;i++){
    cout<<a[i]<<" ";
  }
  cout<<endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值