前言:

快速排序可真是太经典啦!当然,我的复现并没有实现调用一个排序参考函数来实现对不同类型数据进行排序这一功能。

快速排序其中的一大重要思想就是分而治之,采取不断二分的方式进行排序,时间复杂度O(nlog(n)),当然最坏的情况是每次都得二分,复杂度会到O(n^2)

空间复杂度由于涉及到递归的复杂度,我本身理解的也不是很深刻,就不误人子弟了,推荐这篇文章,关于复杂度的部分写的很好!链接放下头了:

———————————————————————————————————————————

2022.11.27,链接失效了= =,不知道为啥

http://t.csdn.cn/lJDzg

———————————————————————————————————————————

思路:

快速排序的基本思路就是不断对数组进行二分,分而治之进行排序的,需要用到递归的知识。我们举个栗子:

5 7 4 6 9 2

1.那么,如何进行二分?如其名,二分,我们首先需要准备两个指针 left 和 right,正如其名,一个最初指向需要排序的最左边的下标,一个指向需要排序的最右边的下标。但是,具体写代码过程中我们函数需要的形参我使用了left 和 right 来传递需要进行排序的区间,所以在函数内部,我们使用 i 来代表left,j 来代表right。

5 7 4 6 9 2
i j

2.然后,我们需要制定一个进行排序的标准大小,通常使用需要排序的数组中的第一个元素,比较方便使用。我们最终需要的状态是这个元素的左边都是比他小的数(不必在乎顺序)右边都是比他大的数字。(显然,这个元素不在最初的位置,当然我们也可以开辟一个辅助数组来进行存储,不过没有这个必要),最终需要得到下列这个形式,那么思考我们如何可以得到这样一个数组

(其实得到这样一个数组,基本就理解这个算法了,剩下的就是进行递归,简简单单两行,所以精髓就是理解如何得到如下的数组。)

4 2 5 6 9 7
i,j

首先,我们定义一个flag,用来标记最初的排序基准数(为了方便我们选择数组的第一个数)。因为不能同时从两边移动 i 和 j 因此我们需要确定一下先动谁,这个地方的不一样会导致整体代码有微小的差异,这里我选择的是先动左边的 j 。

然后我们回顾一下整体的思路,需要把比基准数大的移到右边,比基准数小的移到左边。

因此,我们的 j 的移动标准就是比基准数大的数我们不管他(因为J是从最右边开始移动的,而右边的都得是比基准数大的数),如果遇到比基准数小的数,我们停下。

然后移动 i ,i 的移动标准就是比基准数小的数我们不管他,遇到比基准数大的数我们停下。然后交换 i, j 下标对应的数,一次交换完成。

因为要不停的交换,所以我们外层套的判断条件应该是while,条件呢?当 i 和 j 相遇了,我们就不用继续往下交换数字了,所以我们可以写 i != j 作为判断条件,当然放宽一些,最好写 i < j 作为判断条件。同时,这里我们需要注意内层移动 i 和 j 的时候,会出现 j 移动到 i 左边(因为这是内层的循环,外层控制不到)所以,内层的几个while 和 if 我们都需要套上判断条件 i < j 。

while (i < j){while (arr[j] >= flag && i < j)j--;while (arr[i] <= flag && i < j)i++;if (i < j)swap(&arr[i], &arr[j]);}

用我们举得列子来说我们就变成了这样:

5 2 4 6 9 7
j i

这样就很好理解了,我们还需要把 j 对应下标的数字 同一开始的基准数进行一次交换。得到第一次排序的最终样式:

4 2 5 6 9 7
j i

3.第一次排序我们完成了,接下来我们只需要用递归的思路,对标记左边的,右边的两端分别递归调用函数就可以了。其中左右差不多,说一下左边的范围 [left, j-1] 因为基准的位置是 j ,同时基准数的位置是合理的。所以,我们接下来需要排序的就是不包含基准数的右边半区的数组,最左边界自然是我们传入的排序左边界left,因此范围是[left, j-1]。

//这边为什么用j呢?因为
QuickSort(arr,left,j - 1);
QuickSort(arr,j + 1,right);

写到这,我们可以在函数最前头上加上一个简单出口,加快函数的执行效率:

if (left >= right)return;

因为当我们进行递归调用的时候,必然会把长度区间缩小,缩小到1的时候就没必要进行排序了,这也是这个函数的出口之一。

完整排序代码如下:

void QuickSort(int *arr,int left,int right)
{if (left >= right)return;int i, j;int flag = arr[left];i = left, j = right;while (i < j){while (arr[j] >= flag && i < j)j--;while (arr[i] <= flag && i < j)i++;if (i < j)swap(&arr[i], &arr[j]);}swap(&arr[left],&arr[j]);QuickSort(arr,left,j - 1);QuickSort(arr,j + 1,right);
}

测试代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define N 30//之前写过了,就不再全写一遍了
void generate_random_number(int*, int, int);
void swap(int*, int*);void QuickSort(int *arr,int left,int right)
{if (left >= right)return;int i, j;int flag = arr[left];i = left, j = right;while (i < j){while (arr[j] >= flag && i < j)j--;while (arr[i] <= flag && i < j)i++;if (i < j)swap(&arr[i], &arr[j]);}swap(&arr[left],&arr[j]);QuickSort(arr,left,j - 1);QuickSort(arr,j + 1,right);
}int main()
{int arr[N + 10] = { 0 };generate_random_number(arr, 0, 1024);QuickSort(arr,0,N-1);printf("排序后数列:\n");for (int i = 0; i < N; i++)printf("%d ", arr[i]);printf("\n");return 0;
}

测试结果如下:

至此,QuickSort(快速排序)完成

QuickSort(快速排序)——C语言实现相关推荐

  1. JavaScript实现QuickSort快速排序算法(附完整源码)

    JavaScript实现QuickSort快速排序算法(附完整源码) Comparator.js完整源代码 Sort.js完整源代码 QuickSort .js完整源代码 Comparator.js完 ...

  2. JAVA:实现QuickSort快速排序算法(附完整源码)

    JAVA:实现QuickSort快速排序算法 package com.thealgorithms.sorts;import static com.thealgorithms.sorts.SortUti ...

  3. 【算法图文动画详解系列】QuickSort 快速排序算法

    快排简介 快速排序(Quicksort)是对冒泡排序算法的一种改进. 快速排序由C. A. R. Hoare在1960年提出.它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的 ...

  4. 冒泡排序 选择排序 快速排序(C语言)

    #include <stdio.h> #include <stdlib.h> #include <time.h> //用到了time函数#define arrayS ...

  5. 快速排序c语言实现,快速排序的C语言代码实现

    快速排序实质上是对"冒泡排序"的一种改进,整个排序过程可概括为:通过N趟的排序将原本的排序数据分为若干块进行分块排序,而在每趟排序过程中,以指定的关键字将待排数据分别分为比关键字大 ...

  6. QuickSort 快速排序

    快速排序算法: 思路: 在QSort函数中,设置一个枢轴pivot,Partition函数中选择第一个数当作枢轴变量,经过循环交换,使得它左边的值都比它小,右边的值比它大:然后再递归调用QSort函数 ...

  7. 快速排序c语言单链表代码,快速排序算法及源代码(C语言)

    快速排序是对冒泡排序的一种改进.它的基本思想是:通过一躺排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一不部分的所有数据都要小,然后再按次方法对这两部分数据分别进行快速排序,整个排 ...

  8. c++ 快速排序_C语言必学的12个排序算法:归并排序(第8篇)

    题外话很多童鞋感受算法比较难度,的确,算法其实和C语言本身关系不大,算法是计算机科学家利用丰富的数学和算法设计知识研究出来,如今我们只需拿来主义,学习使用即可,当然这需要一定的努力过程. [C语言必学 ...

  9. c语言对随机数进行快速排序,C语言快速排序与二分查找算法示例

    本文实例讲述了C语言二分排序与查找算法.分享给大家供大家参考,具体如下: 题目:首先产生随机数,再进行快速排序,再进行二分查找. 实现代码: #include #include #include vo ...

  10. 快速排序C语言实现(源代码)

    快速排序 对一个元素个数为20个的随机数组进行快速排序 #include<stdio.h> #include<stdlib.h> #include <time.h> ...

最新文章

  1. 排除计算机故障的顺序,计算机故障排除.ppt
  2. 计算机生物学美国直博,毕业生说 | 生物学全奖直博女生,遍访名校书写芳华
  3. Python3算法基础练习:编程100例( 31 ~ 35 )
  4. 计算机视觉:图像分类定位(单一目标检测)python实现
  5. OpenCV OMZ MTCNN人脸检测的实例(附完整代码)
  6. MySQL索引背后的数据结构及算法原理----惊叹的深入
  7. Java入门算法(动态规划篇1:初识动规)
  8. php-fpm和php,phpcgi和phpfpm的区别是什么
  9. python3 for循环_从零开始学习PYTHON3讲义(六)for循环跟斐波那契数列
  10. Linux 命令之 iwlist 命令-从无线网卡获取更详细的无线信息
  11. ie不加载jre_详细讲解!从JVM直到类加载器
  12. java批量导入和批量删除_MyBatis 实现批量插入和删除中双层循环的写法案例
  13. 3dContactPointAnnotationTool开发日志(八)
  14. Python的遗传算法GA优化深度置信网络DBN超参数回归预测
  15. java 泛型编程_java 泛型编程简介
  16. 坚果pro2刷回官方_坚果Pro2刷机教程刷TWRP面具详细步骤_软件开发_IT综合服务
  17. Arch LinuxLinux引导教程 2021.7.22
  18. java work stealing_工作窃取(work-stealing)算法
  19. Project2016创建WBS并且进行相关设置
  20. python爬虫图片工具安卓版下载_python爬虫之图片下载APP1.0

热门文章

  1. Internet与Web技术的基本概念
  2. iPad mini将如何从重新定义小尺寸平板?
  3. 计算机不能进入桌面,win7系统电脑开机后无法进入桌面的解决方法
  4. MacBook 苹果笔记本 下载Xcode历史版本
  5. JMeter接口测试___参数化方法
  6. S5PV210之UBOOT-2011.06启动过程解析-基于u-boot for tiny210 ver3.1 (by liukun321咕唧咕唧)
  7. LAMP架构与搭建论坛
  8. 模板注入SSTi笔记
  9. STemWin主要控件
  10. java魔兽游戏_.netframework游戏编程入门——模拟魔兽学院永远的羁绊