快速排序算法C语言版

快速排序(Quicksort)是对冒泡排序的一种改进。

快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。

一趟快速排序的算法是:

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]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)。

示例:假设用户输入了如下数组:

创建变量i=0(指向第一个数据), j=5(指向最后一个数据), k=6(赋值为第一个数据的值)。

我们要把所有比k小的数移动到k的左面,所以我们可以开始寻找比6小的数,从j开始,从右往左找,不断递减变量j的值,我们找到第一个下标3的数据比6小,于是把数据3移到下标0的位置,把下标0的数据6移到下标3,完成第一次比较:

i=0   j=3   k=6

接着,开始第二次比较,这次要变成找比k大的了,而且要从前往后找了。递加变量i,发现下标2的数据是第一个比k大的,于是用下标2的数据7和j指向的下标3的数据的6做交换,数据状态变成下表:

i=2 j=3 k=6

称上面两次比较为一个循环。

接着,再递减变量j,不断重复进行上面的循环比较。

在本例中,我们进行一次循环,就发现i和j“碰头”了:他们都指向了下标2。于是,第一遍比较结束。得到结果如下,凡是k(=6)左边的数都比它小,凡是k右边的数都比它大:

如果i和j没有碰头的话,就递加i找大的,还没有,就再递减j找小的,如此反复,不断循环。注意判断和寻找是同时进行的。

然后,对k两边的数据,再分组分别进行上述的过程,直到不能再分组为止。

注意:第一遍快速排序不会直接得到最终结果,只会把比k大和比k小的数分到k的两边。为了得到最后结果,需要再次对下标2两边的数组分别执行此步骤,然后再分解数组,直到数组不能再分解为止(只有一个数据),才能得到正确结果。

调用函数

在c++中可以用函数qsort()可以直接为数组进行排序。

用 法:

void qsort(void *base, int nelem, int width, int (*fcmp)(const void *,const void *));

参数:

  1 待排序数组首地址

  2 数组中待排序元素数量

  3 各元素的占用空间大小

  4 指向函数的指针,用于确定排序的顺序

C语言版本

 1 void sort(int *a, int left, int right)
 2 {
 3     if(left >= right)/*如果左边索引大于或者等于右边的索引就代表已经整理完成一个组了*/
 4     {
 5         return ;
 6     }
 7     int i = left;
 8     int j = right;
 9     int key = a[left];
10
11     while(i < j)                               /*控制在当组内寻找一遍*/
12     {
13         while(i < j && key <= a[j])
14         /*而寻找结束的条件就是,1,找到一个小于或者大于key的数(大于或小于取决于你想升
15         序还是降序)2,没有符合条件1的,并且i与j的大小没有反转*/
16         {
17             j--;/*向前寻找*/
18         }
19
20         a[i] = a[j];
21         /*找到一个这样的数后就把它赋给前面的被拿走的i的值(如果第一次循环且key是
22         a[left],那么就是给key)*/
23
24         while(i < j && key >= a[i])
25         /*这是i在当组内向前寻找,同上,不过注意与key的大小关系停止循环和上面相反,
26         因为排序思想是把数往两边扔,所以左右两边的数大小与key的关系相反*/
27         {
28             i++;
29         }
30
31         a[j] = a[i];
32     }
33
34     a[i] = key;/*当在当组内找完一遍以后就把中间数key回归*/
35     sort(a, left, i - 1);/*最后用同样的方式对分出来的左边的小组进行同上的做法*/
36     sort(a, i + 1, right);/*用同样的方式对分出来的右边的小组进行同上的做法*/
37                        /*当然最后可能会出现很多分左右,直到每一组的i = j 为止*/
38 }
时间: 2024-10-08 01:12:16

快速排序算法C语言版的相关文章

快速排序算法-C语言实现

注:本篇内容为翻译,之所以选择这篇进行翻译原因是该文章含有动画,能够更加直观地展示快速排序.同时,可以仔细看一下代码,代码中把结构化的思想给予了更加充分地表现.按照功能进行模块划分的思想得到了彻底地贯彻. 以下内容翻译自: http://cprogramminglanguage.net/quicksort-algorithm-c-source-code.aspx 译文: 在快速排序算法中,使用了分治策略.首先把序列分成两个子序列,递归地对子序列进行排序,直到整个序列排序结束. 步骤如下: 在序列

六种排序算法C语言版(上)

排序即将一个无序的数组(序列)按照一定的规则排列,常见的规则便是按照从大到小或者从小到大的顺序.本文讨论的排序一律指按照从小到大的顺序进行排列的这种情况. 本文将分为上下两章介绍以下六种排序算法: (1)直接选择排序 (2)冒泡排序 (3)快速排序 (4)二分排序 (5)堆排序 (6)线性时间排序. 首先,直接选择排序.直接选择排序的思想是: 1.第一次从数组A[0]到A[n-1]中选出最小的然后与A[0]进行交换: 2.第二次从A[1]到A[n-1]中选择最小的然后与A[1]进行交换: 依次类

交换排序---快速排序算法(Javascript版)

快速排序是对冒泡排序的一种改进.通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,最终达到整个数据变成有序序列. 假设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为基准数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序.值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对

排序算法——C#语言版

插入排序:(直接插入排序&希尔排序) using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Sort { public class InsertSort { public static int k; /// <summary> /// 直接插入排序 /// </summary> /// <param name="a&quo

排序算法总结(C语言版)

1.    插入排序 1.1     直接插入排序 1.2     Shell排序 2.    交换排序 2.1     冒泡排序 2.2     快速排序 3.    选择排序 3.1     直接选择排序 3.2     堆排序 4.    归并排序 4.1     二路归并排序 4.2     自然合并排序 5.    分布排序 5.1     基数排序 1.插入排序 1.1      直接插入排序 将已排好序的部分num[0]~num[i]后的一个元素num[i+1]插入到之前已排好序的

基于BP神经网络的简单字符识别算法自小结(C语言版)

本文均属自己阅读源码的点滴总结,转账请注明出处谢谢. 欢迎和大家交流.qq:1037701636 email:[email protected] 写在前面的闲话: 自我感觉自己应该不是一个很擅长学习算法的人,过去的一个月时间里因为需要去接触了BP神经网络.在此之前一直都认为算法界的神经网络.蚁群算法.鲁棒控制什么的都是特别高大上的东西,自己也就听听好了,未曾去触碰与了解过.这次和BP神经网络的邂逅,让我初步掌握到,理解透彻算法的基本原理与公式,转为计算机所能识别的代码流,这应该就是所谓的数学和计

C语言快速排序算法代码分析

最近在很多场合都看见设计模式的影子,一直以来,都投入主要时间在搞算法与数据结构,很来发现设计模式真的很重要.有的时候代码的可维护.可重用.可扩展确实胜过单纯的算法效率高.所以拾起大牛书籍<大话设计模式>同时参考网上诸大牛的博客,开始我的设计模式之旅.由于平时编程时用C/C++,现在是Java,也练练Java语法. 今天先介绍一下命令模式. 概念: 命令模式(Command):将一个请求封装成一个对象,从而使你可用不同的请求对象对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作.

python版的快速排序算法源码

下面的代码段是关于python版的快速排序算法的代码,应该对各位朋友有用途. def qsort(L): return ((qsort([x for x in L[1:] if x < L[0]]) + L[0:1] + qsort([x for x in L[1:] if x >= L[0]]) ) if L else []) 版本2 def qsort3(arr, l, r): def swap(arr, s, d): if s != d: tmp = arr[s] arr[s] = ar

C语言版数据结构算法

C语言版数据结构算法 C语言数据结构具体算法 https://pan.baidu.com/s/19oLoEVqV1I4UxW7D7SlwnQ C语言数据结构演示软件 https://pan.baidu.com/s/1u8YW897MjJkoOfsbHuadFQ 在上一篇的FIFO中就是基于数据结构思维中的队列实现的,而基本的数据结构内容还有 算法效率分析.线性表.栈和队列.串.数组和广义表.树和二叉树.图.查表.排序.动态存储管理 上面两个链接就是<数据结构(C语言版)>严蔚敏教授严奶奶的书籍