快速排序是对冒泡排序的一种改进。它的基本思想是:通过一躺排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一不部分的所有数据都要小,然后再按次方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
假设要排序的数组是A[1]……A[N],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一躺快速排序。一躺快速排序的算法是:
1)、设置两个变量I、J,排序开始的时候I:=1,J:=N;
2)以第一个数组元素作为关键数据,赋值给X,即X:=A[1];
3)、从J开始向前搜索,即由后开始向前搜索(J:=J-1),找到第一个小于X的值,两者交换;
4)、从I开始向后搜索,即由前开始向后搜索(I:=I+1),找到第一个大于X的值,两者交换;
5)、重复第3、4步,直到I=J;
例如:待排序的数组A的值分别是:(初始关键数据X:=49)
A[1] A[2] A[3] A[4] A[5] A[6] A[7]:
49 38 65 97 76 13 27
进行第一次交换后: 27 38 65 97 76 13 49
( 按照算法的第三步从后面开始找
进行第二次交换后: 27 38 49 97 76 13 65
( 按照算法的第四步从前面开始找>X的值,65>49,两者交换,此时I:=3 )
进行第三次交换后: 27 38 13 97 76 49 65
( 按照算法的第五步将又一次执行算法的第三步从后开始找
进行第四次交换后: 27 38 13 49 76 97 65
( 按照算法的第四步从前面开始找大于X的值,97>49,两者交换,此时J:=4 )
此时再执行第三不的时候就发现I=J,从而结束一躺快速排序,那么经过一躺快速排序之后的结果是:27 38 13 49 76 97 65,即所以大于49的数全部在49的后面,所以小于49的数全部在49的前面。
快速排序就是递归调用此过程——在以49为中点分割这个数据序列,分别对前面一部分和后面一部分进行类似的快速排序,从而完成全部数据序列的快速排序,最后把此数据序列变成一个有序的序列,根据这种思想对于上述数组A的快速排序的全过程如图6所示:
初始状态 {49 38 65 97 76 13 27}
进行一次快速排序之后划分为 {27 38 13} 49 {76 97 65}
分别对前后两部分进行快速排序 {13} 27 {38}
结束 结束 {49 65} 76 {97}
49 {65} 结束
结束
图6 快速排序全过程
1)、设有N(假设N=10)个数,存放在S数组中;
2)、在S[1。。N]中任取一个元素作为比较基准,例如取T=S[1],起目的就是在定出T应在排序结果中的位置K,这个K的位置在:S[1。。K-1]<=S[K]<=S[K+1..N],即在S[K]以前的数都小于S[K],在S[K]以后的数都大于S[K];
3)、利用分治思想(即大化小的策略)可进一步对S[1。。K-1]和S[K+1。。N]两组数据再进行快速排序直到分组对象只有一个数据为止。
如具体数据如下,那么第一躺快速排序的过程是:
数组下标: 1 2 3 4 5 6 7 8 9 10
45 36 18 53 72 30 48 93 15 36
I J
(1) 36 36 18 53 72 30 48 93 15 45
(2) 36 36 18 45 72 30 48 93 15 53
(3) 36 36 18 15 72 30 48 93 45 53
(4) 36 36 18 15 45 30 48 93 72 53
(5) 36 36 18 15 30 45 48 93 72 53
通过一躺排序将45放到应该放的位置K,这里K=6,那么再对S[1。。5]和S[6。。10]分别进行快速排序。
一般来说,冒泡法是程序员最先接触的排序方法,它的优点是原理简单,编程实现容易,但它的缺点就是--程序的大忌--速度太慢。下面我介绍一个理解上简单但编程实现上不是太容易的排序方法,我不知道它是不是现有排序方法中最快的,但它是我见过的最快的。排序同样的数组,它所需的时间只有冒泡法的 4% 左右。我暂时称它为“快速排序法”。
“快速排序法”使用的是递归原理,下面我结合一个例子来说明“快速排序法”的原理。首先给出一个数组{53,12,98,63,18,72,80,46, 32,21},先找到第一个数--53,把它作为中间值,也就是说,要把53放在一个位置,使得它左边的值比它小,右边的值比它大。{21,12,32, 46,18,53,80,72,63,98},这样一个数组的排序就变成了两个小数组的排序--53左边的数组和53右边的数组,而这两个数组继续用同样的方式继续下去,一直到顺序完全正确。
我这样讲你们是不是很胡涂,不要紧,我下面给出实现的两个函数:
/*
n就是需要排序的数组,left和right是你需要排序的左界和右界,
如果要排序上面那个数组,那么left和right分别是0和9
*/
void quicksort(int n[], int left,int right)
{
int dp;
if (left<right) {
/*
这就是下面要讲到的函数,按照上面所说的,就是把所有小于53的数放
到它的左边,大的放在右边,然后返回53在整理过的数组中的位置。
*/
dp=partition(n,left,right);
quicksort(n,left,dp-1);
quicksort(n,dp+1,right); //这两个就是递归调用,分别整理53左边的数组和右边的数组
}
}
我们上面提到先定位第一个数,然后整理这个数组,把比这个数小的放到它的左边,大的放右边,然后
返回这中间值的位置,下面这函数就是做这个的。
int partition(int n[],int left,int right)
{
int lo,hi,pivot,t;
pivot=n[left];
lo=left-1;
hi=right+1;
while(lo+1!=hi) {
if(n[lo+1]<=pivot)
lo++;
else if(n[hi-1]>pivot)
hi--;
else {
t=n[lo+1];
n[++lo]=n[hi-1];
n[--hi]=t;
}
}
n[left]=n[lo];
n[lo]=pivot;
return lo;
}
比如:一个数组和三个指针,第一个指针称为p指针,在整个过程结束之前它牢牢的指向第一个数,第二个指针和第三个指针分别为lo指针和hi指针,分别指向最左边的值和最右边的值。lo指针和hi指针从两边同时向中间逼近,在逼近的过程中不停的与p指针的值比较,如果lo指针的值比p指针的值小,lo++,还小还++,再小再++,直到碰到一个大于p指针的值,这时视线转移到hi指针,如果 hi指针的值比p指针的值大,hi--,还大还--,再大再--,直到碰到一个小于p指针的值。这时就把lo指针的值和hi指针的值做一个调换。持续这过程直到两个指针碰面,这时把p指针的值和碰面的值做一个调换,然后返回p指针新的位置。
#include<iostream>
using namespace std;
int a[200001],n;
void swap(int &a,int &b){
int tmp = a;
a = b;
b = tmp;
}
int partition(int p,int r){
int rnd = rand()%(r-p+1)+p;
swap(a[rnd],a[r]);
int pvt = r, i = p-1;
for(int j = i+1;j<r;j++)
if(a[j]<a[pvt])
swap(a[j],a[++i]);
swap(a[++i],a[pvt]);
return i;
}
void qsort(int p,int r){
if(p<r){
int q = partition(p,r);
qsort(p,q-1);
qsort(q+1,r);
}
}
int main(){
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
qsort(0,n-1);
for(int i=0;i<n;i++)
cout<<a[i];
return 0;
}
分享到:
相关推荐
下面将详细介绍快速排序算法的实现细节。 首先,我们需要了解快速排序算法的基本思想。快速排序算法的核心思想是选择一个枢轴元素,然后将记录分区为两部分,左边的记录的键值小于或等于枢轴元素,右边的记录的键值...
### 超快速排序算法详解 #### 一、引言 在计算机科学中,排序算法是一种重要的基础算法,被广泛应用于各种系统软件和应用软件之中。传统的排序算法如快速排序和基数排序各有优缺点:快速排序算法因其简洁的结构和...
快速排序算法,是排序算法中的经典之作,由英国计算机科学家C.A.R. Hoare在1960年提出,以其高效的平均性能而闻名。 快速排序的基本思想是分治法。首先选择一个“基准”元素,然后将数组分为两部分:一部分的元素都...
在计算机科学领域,数据结构和排序算法是至关重要的基础,它们直接影响到程序的效率和性能。本文将深入探讨“数据结构排序算法”这一主题,主要关注描述中提到的五种排序算法:插入排序、交换排序、选择排序、归并...
本篇文章将详细讨论几种常见的排序算法:选择排序、冒泡排序、插入排序、合并排序以及快速排序,分析它们的算法原理、时间效率,并通过经验分析验证理论分析的准确性。 **1. 选择排序(Selection Sort)** 选择排序...
总结起来,本文介绍了使用 MATLAB 技术实现快速排序算法的方法。通过对待排序序列的递归划分和排序,快速排序算法能够高效地完成排序任务。同时,我们还提到了快速排序算法的时间复杂度以及避免最坏情况的优化措施。...
本文详细介绍了指针在快速排序算法中的作用,包括分区操作、递归排序以及快速排序的变体。希望读者能够通过本文深入理解快速排序算法,并掌握指针在算法实现中的关键应用。随着对快速排序更深入的探索,你会发现它在...
该资源详细介绍了如何使用Python语言实现快速排序算法(Quick Sort)。快速排序是一种高效的排序算法,具有较好的平均时间复杂度O(n log n),在大多数情况下比其他排序算法表现更佳。资源中包括了快速排序的基本原理...
本文详细介绍了针对 `CObList` 实现的快速排序算法及其代码实现细节。通过对代码逐行解析,我们不仅了解了快速排序的基本思想,还掌握了如何在实际项目中应用这一高效排序算法。希望本文能够帮助读者更好地理解和...
本文主要介绍了一种基于Java的按位拆分快速排序算法,旨在解决计算机科学中最重要的研究问题之一,即排序问题。传统的排序算法如冒泡排序算法、选择排序算法等,其运算效率不高,且其数据对象的适应范围受到限制。...
根据提供的文件信息,我们可以深入探讨快速排序算法的原理与实现。 ### 快速排序算法概述 快速排序是一种高效的排序算法,由英国计算机科学家托尼·霍尔(Tony Hoare)在1960年提出。它采用分治策略来把一个序列...
### 十种排序算法介绍 #### 一、概述 本文旨在详细介绍十种常见的排序算法,这些算法不仅是计算机科学的基础组成部分,也是数据结构课程中的重要内容。排序算法被广泛应用于各种场景,如数据库管理、搜索引擎结果...
下面将对这些排序算法进行详细介绍。 1. **冒泡排序**:这是一种简单的排序算法,通过不断交换相邻的错误顺序元素来逐步排序。它的主要思想是重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把...
这篇论文是计算机科学领域的经典文献之一,首次详细介绍了快速排序算法的原理和实现方法。 在这篇论文中,霍尔描述了一种新的排序方法,该方法适用于计算机的随机访问存储器。他比较了这种方法与其他已知的排序方法...
下面将逐一详细介绍这些排序算法及其原理。 1. 快速排序:由C.A.R. Hoare提出,是一种采用分治策略的高效排序算法。其核心思想是选取一个基准元素,将数组分为两部分,一部分的所有元素都比基准小,另一部分的所有...
为了进一步提高排序效率,本文介绍了一种改进的快速排序算法——结合了插入排序的优点。 #### 二、快速排序的改进 快速排序是一种基于分治策略的排序算法,通过递归地将数组分割成更小的部分,并对这些部分进行...
本资源"常用排序算法介绍_示例程序"提供了一个深入理解这些算法的平台,结合了理论与实践,帮助开发者直观地看到各种排序算法的工作过程。 首先,让我们逐一探讨这些排序算法的核心思想: 1. **冒泡排序**:通过...
### 快速排序算法C语言实现教程知识点详解 #### 一、快速排序的基本概念 快速排序(QuickSort)是一种高效且广泛应用的排序算法,它基于**分治法**的思想来进行数据排序。快速排序的核心思想是选取一个基准元素,...