数据结构——快速排序算法

今天来说一说快速排序:

基本思想:

  1. 任取一个元素 (如第一个) 为轴点
  2. 所有比它小的元素一律前放,比它大的元素一律后放,形成左右两个子表
  3. 对各子表重新选择中心元素并依此规则调整,直到每个子表的元素只剩一个

注意:

  • 每一趟的子表的形成是采用从两头向中间交替式逼近法
  • 由于每趟中对各子表的操作都相似,可采用递归算法

代码实现:

#include <iostream>
using namespace std;

//找到第一个轴点,以这个轴点为界,将待排序的数组划分为
//[low,pivot),[pivot],(pivot,high]三部分
int Partition(int a[], int low, int high)
{
    if( low > high )//判断非法条件
        return -1;
    int pivot = a[low];//将轴点默认为数组的第一个元素a[low](备份)
    while (low < high)//从数组的两端 交替地 向中间扫描
    {
        while (low < high && pivot <= a[high])//在不小于pivot的前提下
        {
            high--;//向左拓展右端子序列
        }
        a[low] = a[high];//小于pivot的值归入左侧子序列
        while (low < high && pivot >= a[low])//在不大于pivot的前提下
        {
            low++;//向右拓展左端子序列
        }
        a[high] = a[low];//大于pivot的的值归入右侧子序列
    }
    a[low] = pivot;//将备份的轴点记录置于左、右子序列之间
    return low;//返回轴点的下标
}

//快排算法(递归)
void QuickSort(int a[], int low, int high)
{
    if (high - low < 2)//只有一个值是默认有序的,不必再进行排序
    {
        return;
    }
    int key = Partition(a,low,high);//找到轴点的下标
    QuickSort(a,low,key-1);//递归进行排序。一旦找到轴点就可以确定这个轴点
    QuickSort(a,key+1,high);//的位置就是排序后的的位置,所以不必再进行排序。
}

/*------测试代码------*/
int main()
{
    //int a[] = {1,2,4,3,12,45,2,54,6,32,44};
    int a[] = {21,21,54,6,3,44,5,5,65,33};
    int La = sizeof(a)/sizeof(a[0]) - 1;//这里必须减一,因为数组下标是从0开始的,否则会造成数组越界
    QuickSort(a,0,La);
    for (int i =0; i <= La; i++)
    {
        cout<<a[i]<<endl;
    }
    return 0;
}

输出结果:

时间效率: O(nlog2n) —每趟确定的元素呈指数增加

空间效率: O(log2n)—递归要用到栈空间

稳 定 性: 不稳定 —可选任一元素为支点。

时间: 2024-10-26 08:04:00

数据结构——快速排序算法的相关文章

数据结构-快速排序算法

一趟快速排序的算法是: 1)设置两个变量i.j,排序开始的时候:i=0,j=N-1: 2)以第一个数组元素作为关键数据,赋值给key,即key=A[0]: 3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]和A[i]互换: 4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]互换: 5)重复第3.4步,直到i=j: (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于ke

数据结构与算法之--高级排序:shell排序和快速排序【未完待续】

高级排序比简单排序要快的多,简单排序的时间复杂度是O(N^2),希尔(shell)排序的是O(N*(logN)^2),而快速排序是O(N*logN). 说明:下面以int数组的从小到大排序为例. 希尔(shell)排序 希尔排序是基于插入排序的,首先回顾一下插入排序,假设插入是从左向右执行的,待插入元素的左边是有序的,且假如待插入元素比左边的都小,就需要挪动左边的所有元素,如下图所示: ==> 图1和图2:插入右边的temp柱需要outer标记位左边的五个柱子都向右挪动 如图3所示,相比插入排序

python数据结构与算法 35 快速排序

快速排序 快速排序也使用了分而治之的策略来提高性能,而且不需要额外的内存,但是这么做的代价就是,列表不是对半切分的,因而,性能上就有所下降. 快速排序选择一个数值,一般称为"轴点",虽然有很多选取轴点的方法,我们还是简单地把列表中第一个元素做为轴点了.轴点的作用是帮助把列表分为两个部分.列表完成后,轴点所在的位置叫做"切分点",从这一点上把列表分成两部分供后续调用. 图12所示,54将作为轴点.这个例子我们已经排过多次了,我们知道54在排好序后将处于现在31的位置上

[数据结构和算法]快速排序笔记

特点:1.是冒泡的改进2.是一个递归的过程3.不稳定 4.时间复杂度:O(nlogn) 设要排序的数组是A[0]...A[n-1],首先取数组的第一个数作为关键数据,然后将所有比它小的数都放到它的前面,比他大的都放到他的后面,这个过程被称为一趟快速排序 算法步骤:1.设置两个变量i,j,排序开始i = 0, j = N-1;2.以第一个数组元素作为关键字,Key = A[0];3.从J开始向前搜索,即由后开始向前搜索j--, 找到第一个小于key的值A[j],将A[j]赋值给A[i]4.从I开始

JavaScript 数据结构与算法之美 - 归并排序、快速排序、希尔排序、堆排序

1. 前言 算法为王. 想学好前端,先练好内功,只有内功深厚者,前端之路才会走得更远. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 JavaScript ,旨在入门数据结构与算法和方便以后复习. 之所以把归并排序.快速排序.希尔排序.堆排序放在一起比较,是因为它们的平均时间复杂度都为 O(nlogn). 请大家带着问题:快排和归并用的都是分治思想,递推公式和递归代码也非常相似,那它们的区别在哪里呢 ? 来阅读下文. 2. 归并排序(Merge Sort) 思想 排序一个数

数据结构排序算法之快速排序

排序算法包括很多种,其中快速排序是其中一种比较快的排序算法,今天就来介绍一下: 快速排序的基本实现思想就是将当前待排序列分成两个部分.一个值.一个值:就是选定出一个值作为被比较的元素.两个部分:所有比该被选定元素大的部分都去该元素的右边,所有比被选定元素小的部分都去该元素的左边.这样我们就确定了该元素在这个待排序列中的位置,其实也就是我们已经将这个元素“排好了”. 那么,怎么才能完成一次的快速排序呢? 我们选定一个被比较的元素,一般都是选第一个,即数组中第一个元素作为val,然后我们给出两个指针

数据结构之排序算法Java实现(4)—— 交换类排序之快速排序算法

快速排序算法属于"交换类"的排序,它的效率主要跟数据分布是否对称有关. 升序排序: /** * 快速排序 * 升序排序 */ @Override public <T extends Comparable<? super T>> void sortByAsc(T[] data) { if(data == null || data.length <= 1){ return; } partitionSortByAsc(data, 0, data.length -

数据结构和算法之排序二:快速排序

上一篇文章我们讲完了归并排序,对于分而治之和递归思想应该都有了一定的理解,这篇文章我们将介绍道被认为是排序算法中最容易出错,但是又是最喜欢使用的一中排序方式,快速排序.对于快速排序而言我们必须抓住几个关键点就是基准值的选取,以及它在递归思想的运用过程中需要注意的事项.我们先看下面的图片了解一下快速排序的过程. 我们可以看出每一次排序过程中都是选取第一个数据作为基准值,然后在前段和末端设置两个指针,指针对应的数据和基准值进行比较,如果大于基准值我们将它放在右边,如果小于基准值,我们就将它放在左边.

Python实现的数据结构与算法之快速排序详解

一.概述 快速排序(quick sort)是一种分治排序算法.该算法首先 选取 一个划分元素(partition element,有时又称为pivot):接着重排列表将其 划分 为三个部分:left(小于划分元素pivot的部分).划分元素pivot.right(大于划分元素pivot的部分),此时,划分元素pivot已经在列表的最终位置上:然后分别对left和right两个部分进行 递归排序. 其中,划分元素的 选取 直接影响到快速排序算法的效率,通常选择列表的第一个元素或者中间元素或者最后一