啊哈算法 之 快速排序

关于效率问题

上篇讲的冒泡排序可以说是我们第一个真正的算法,他解决了桶排序的占用空间过大的问题(因为桶排序要根据排序的数的个数申请指定的内存),但是冒泡排序却牺牲了非常大的效率,假设我们要给1亿的数进行排序,因为桶排序的时间复杂度是O(M+N),而冒泡的是O(N2)N的平方,假设计算机的速度是每秒10亿次,桶排序只需要0.1秒,而冒泡则需要1000万秒,大概115天,这是个很恐怖的数字, 想想都能吓尿人。

基准数

假设我们要对6,1,2,7,9,3,4,5,10,8,这是个数进行排序,我们首先要选个基准数(不要被这个数吓到,这货就是我们拿来做参照的),我们就拿6当基准数吧。

排序原理讲解

下面我们要把比6大的数的放到6的右边,把6小的数放到左边,如何能做到呢,这就要使用上篇冒泡用到的方法,就是进行比较然后交换位置,但是这次我们从两头开始,假设有两个哨兵j和i 。i从6开始,即队首开始,j从8开始,即队尾开始,然后两个哨兵开始向中间寻找大于,小于6的数,哨兵j先出发(为什么j先出发呢,大家可以认真想想这个很重要),那么执行完第一次寻找之后 :3,1,2,5,4,6,7,9,10,8,现在就实现了大于6的在右面,小于的在左边,6的位置已经确定,接着对6左右两个分别开始排序(因为6已经归位了)左面的选3为基准数,然后接着从左边的3,1,2,5,4的五个数组成的队列的两头开始寻找,第一次排序后的结果为2,1,3,5,4接着以在折半一次进行排序。这样就达到了最终的排序了,就是一直折半然后随机选择一个数当基准数,当然基准数如果靠左,这从右边开始,如果靠右就从左边开始,只有这样才能让基准数能正确的归位,这点很重要一定要理解。

关于效率

快速排序之所以快是相比冒泡排序每次交换位置的都是跳跃式的,每次排序设置一个基准数,把小于基准数的放到左边,大于基准数的放到右边,这样就不会像冒泡排序那样每次只能与相邻的数进行比较交换位置那么费事儿,比较的次数少了很多,这样也就提高了效率。因此冒泡排序最坏的就是相邻的数进行交换,这样就和冒泡排序的时间复杂度一致了就是O(N的平方),它的平均时间复杂度是O(nlogN),其实快速排序体现的是一种“二分”思想。好了,下面上代码让大家好好理解理解

实例

#include <stdio.h>
int a[101],n;
void quickSort(int left,int right){ //快速排序
    int i,j,t,temp;
    if (left > right) { //判断参数的正确性
        return;
    }
    temp = a[left];
    i = left;
    j = right;
    while (i != j) { //判断是否相遇
        while (a[j] >= temp && i < j) { //右边的是不是小于基准数
            j--;
        }
        while (a[i] <= temp && i < j) { //左边的是不是大于基准数
            i++;
        }
        if (i < j) { //找到左边大于基准数,右边小于基准数进行交换
            t = a[i];
            a[i] = a[j];
            a[j] = t;
        }
    }
    a[left] = a[i]; //相遇了,把基准数位置进行调整
    a[i] = temp;
    quickSort(left, i - 1); //递归的方法进行基准数左边的数进行调整
    quickSort(i + 1, right);//递归的方法进行基准数右边的数进行调整
}
int main(int argc, const char * argv[])
{
    int i,n;
    scanf("%d",&n); //输入数的个数
    for (i = 1; i <= n; i++) { //输入数据
        scanf("%d",&a[i]);
    }
    quickSort(1, n); //使用快速排序对输入的数进行排序
    for (i = 1; i <= n; i++) { //输出排序后的数
        printf("%d ",a[i]);
    }

}

相信大家结合注释都能看懂代码,我就不细说了

结果为:

结果也是能反映俺的代码没问题,好了,大家晚安

时间: 2024-10-01 04:52:26

啊哈算法 之 快速排序的相关文章

排序算法 之 快速排序

快速排序是基于分治思想的一种排序算法,就像该方法的名字一样,速度比较快,所以叫做快速排序:它的平均时间复杂度为O(N*logN),最坏时间复杂度为O(n2),由于快速排序在序列元素数量多的时候速度比较快,所以很多语言内置的排序方法也是用快速排序实现的.快速排序也有很多优化的版本,比如在排序时基数的选择等等-下面就说一下一般的快速排序的实现. 基本思想: 快速排序的基本思想就是,先从待排序的序列中任选一个元素作为基数,然后将序列中的其他小于基数的元素放在基数的左边,大于或等于基数的元素放在基数的右

算法:快速排序

原理: 在一个数组中,选一个元素(通常是第一个元素或者数组的中间元素)与剩余的其它元素进行比较:建立两个分组(左组和右组),比当前元素小的放在左组,比当前元素大的放在右组.这样一来,将左组,中间组合右组合并起来就形成一个已经“排好序”的数组.实际上,左组和右组中的元素并不一定已经排好序,调用自己去排序,只有左右数组的元素个数大于1,就需要排序,如果元素个数等于一个,就不再调用函数. 使用递归实现(步骤): 1.实现从数组中取出一个元素:将小的放左边数组,大的放右边数组,最后返回合并结果 2. 

十大基础实用算法之快速排序和堆排序

快速排序是由东尼·霍尔所发展的一种排序算法.在平均状况下,排序 n 个项目要Ο(n log n)次比较.在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见.事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来. 快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists). 算法步骤: 1 从数列中挑出一个元素,称为 "基准"(pi

经典白话算法之快速排序

[分析] [伪代码] [运行过程] [代码] /********************************* * 日期:2014-04-01 * 作者:SJF0115 * 题目:快速排序 **********************************/ #include <iostream> #include <stdio.h> using namespace std; //对子数组array[p...r]就地重排 int Partition(int array[],i

啊哈!算法之快速排序与桶排序

啊哈!算法之快速排序与桶排序 1.快速排序算法 快速排序由 C. A. R. Hoare(东尼·霍尔,Charles Antony Richard Hoare)在1960 年提出,之后又有许多人做了进一步的优化.在数列种随机找出一个基准数,因为数列是杂乱的,所以取首项为基准数.从后往前找到比基准数大的位置,再从前往后找到比基准数小的位置,交换元素:右游标向前移动与左游标向后移动,它们相遇时用基准数的位置与相遇的位置交换.此时原来数列以相遇的位置被划分为了两个需要排序的数列,再次执行上述过程:当左

排序算法 一 快速排序

算法:快速排序 思想:通过一趟排序,确定了一个data的最终确切位置.(通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列)  特点:不稳定算法. 代码实现:

算法之快速排序

这里简单的介绍下快速排序的伪代码实现和示意图: QuickSort(A,p,r) if p<r q=Partition(A,p,r) QuickSort(A,p,q-1) QucikSort(A,q+1,r) 算法的关键部位为Partition函数的实现,它实现了对数组A(p,r)的原址排序: Partition(A,p,r) x=A[r] i=p-1 for j=p to r-1 if a[j]<=x i=i+1 exchange a[i] with a[j] exchange A[i+1]

常用排序算法之——快速排序(C语言+VC6.0平台)

经典排序算法中快速排序具有较好的效率,但其实现思路相对较难理解. #include<stdio.h> int partition(int num[],int low,int high) //以key为基准 将待排数列“高”.“低 ”两部分,“高”部分的所有数据比key大,“低”部分的数据都比key小 { int left,right,key; left=low;right=high;key=num[low]; while(left<right) { while(left<right

常用排序算法之——快速排序

快速排序的原理: 首先找一个标兵值,等于某一个元素值:遍历数组,将数组分为小于标兵值和大于标兵值的两部分:然后分别对两个部分采用快速排序,递归. 分开数组时,维持一个指针,指向已找到小部分的最后一个元素:一个指针用于遍历. 不稳定排序算法.当数组已经有序时,时间复杂度最差,为O(N2),平均.最优情况下都为O(N lgN). 代码如下: 1 #include <iostream> 2 using namespace std; 3 4 template<typename T> 5 v

排序算法系列——快速排序

记录学习点滴 快速排序算法是一种很有趣的算法,短小精悍,性能强劲,对于大部分情况都可以胜任,但对极端环境难以应付. 快速排序我理解为:这是一个“以自我为中心的”+“分治法”思想的算法. 分治法不必多说,化繁为简,那就是逐个击破. 那什么是“以自我为中心”?顾名思义,就是每次都一个“我”,每个人都要围绕“我”行事,比“我”小的都去左边站着,比“我”他大的都去右边站着,而且“我”不去关心每一边都有谁,反正你没“我”大或者小就行.一旦“我”落位了妥帖了,“我”就不动了.然后再在左右两边分别产生新“我”