甘肃 网站建设 开发 app,网站颜色设计,电子工厂网站建设,贵阳有做网站的公司吗快速排序介绍
快速排序(Quick Sort)使用分治法策略。 它的基本思想是#xff1a;选择一个基准数#xff0c;通过一趟排序将要排序的数据分割成独立的两部分#xff1b;其中一部分的所有数据都比另外一部分的所有数据都要小。然后#xff0c;再按此方法对这两部分数据分别进…快速排序介绍
快速排序(Quick Sort)使用分治法策略。 它的基本思想是选择一个基准数通过一趟排序将要排序的数据分割成独立的两部分其中一部分的所有数据都比另外一部分的所有数据都要小。然后再按此方法对这两部分数据分别进行快速排序整个排序过程可以递归进行以此达到整个数据变成有序序列。
快速排序流程 (1) 从数列中挑出一个基准值。 (2) 将所有比基准值小的摆放在基准前面所有比基准值大的摆在基准的后面(相同的数可以到任一边)在这个分区退出之后该基准就处于数列的中间位置。 (3) 递归地把基准值前面的子数列和基准值后面的子数列进行排序。
快速排序图文说明
/** 快速排序** 参数说明* a -- 待排序的数组* l -- 数组的左边界(例如从起始位置开始排序则l0)* r -- 数组的右边界(例如排序截至到数组末尾则ra.length-1)*/
void quick_sort(int a[], int l, int r)
{if (l r){int i,j,x;i l;j r;x a[i];while (i j){while(i j a[j] x)j--; // 从右向左找第一个小于x的数if(i j)a[i] a[j];while(i j a[i] x)i; // 从左向右找第一个大于x的数if(i j)a[j--] a[i];}a[i] x;quick_sort(a, l, i-1); /* 递归调用 */quick_sort(a, i1, r); /* 递归调用 */}
} 下面以数列a{30,40,60,10,20,50}为例演示它的快速排序过程(如下图)。 上图只是给出了第1趟快速排序的流程。在第1趟中设置xa[i]即x30。 (01) 从右 -- 左查找小于x的数找到满足条件的数a[j]20此时j4然后将a[j]赋值a[i]此时i0接着从左往右遍历。 (02) 从左 -- 右查找大于x的数找到满足条件的数a[i]40此时i1然后将a[i]赋值a[j]此时j4接着从右往左遍历。 (03) 从右 -- 左查找小于x的数找到满足条件的数a[j]10此时j3然后将a[j]赋值a[i]此时i1接着从左往右遍历。 (04) 从左 -- 右查找大于x的数找到满足条件的数a[i]60此时i2然后将a[i]赋值a[j]此时j3接着从右往左遍历。 (05) 从右 -- 左查找小于x的数没有找到满足条件的数。当ij时停止查找然后将x赋值给a[i]。此趟遍历结束 按照同样的方法对子数列进行递归遍历。最后得到有序数组 时间复杂度和稳定性
快速排序稳定性 快速排序是不稳定的算法它不满足稳定算法的定义。算法稳定性 -- 假设在数列中存在a[i]a[j]若在排序之前a[i]在a[j]前面并且排序之后a[i]仍然在a[j]前面。则这个排序算法是稳定的
快速排序时间复杂度 快速排序的时间复杂度在最坏情况下是O(N2)平均的时间复杂度是O(N*lgN)。 这句话很好理解假设被排序的数列中有N个数。遍历一次的时间复杂度是O(N)需要遍历多少次呢至少lg(N1)次最多N次。 (01) 为什么最少是lg(N1)次快速排序是采用的分治法进行遍历的我们将它看作一棵二叉树它需要遍历的次数就是二叉树的深度而根据完全二叉树的定义它的深度至少是lg(N1)。因此快速排序的遍历次数最少是lg(N1)次。 (02) 为什么最多是N次这个应该非常简单还是将快速排序看作一棵二叉树它的深度最大是N。因此快读排序的遍历次数最多是N次。 代码实现
C语言实现
/*** 快速排序C 语言** author skywang* date 2014/03/11*/#include stdio.h// 数组长度
#define LENGTH(array) ( (sizeof(array)) / (sizeof(array[0])) )/** 快速排序** 参数说明* a -- 待排序的数组* l -- 数组的左边界(例如从起始位置开始排序则l0)* r -- 数组的右边界(例如排序截至到数组末尾则ra.length-1)*/
void quick_sort(int a[], int l, int r)
{if (l r){int i,j,x;i l;j r;x a[i];while (i j){while(i j a[j] x)j--; // 从右向左找第一个小于x的数if(i j)a[i] a[j];while(i j a[i] x)i; // 从左向右找第一个大于x的数if(i j)a[j--] a[i];}a[i] x;quick_sort(a, l, i-1); /* 递归调用 */quick_sort(a, i1, r); /* 递归调用 */}
}void main()
{int i;int a[] {30,40,60,10,20,50};int ilen LENGTH(a);printf(before sort:);for (i0; iilen; i)printf(%d , a[i]);printf(\n);quick_sort(a, 0, ilen-1);printf(after sort:);for (i0; iilen; i)printf(%d , a[i]);printf(\n);
}
c实现
/*** 快速排序C** author skywang* date 2014/03/11*/#include iostream
using namespace std;/** 快速排序** 参数说明* a -- 待排序的数组* l -- 数组的左边界(例如从起始位置开始排序则l0)* r -- 数组的右边界(例如排序截至到数组末尾则ra.length-1)*/
void quickSort(int* a, int l, int r)
{if (l r){int i,j,x;i l;j r;x a[i];while (i j){while(i j a[j] x)j--; // 从右向左找第一个小于x的数if(i j)a[i] a[j];while(i j a[i] x)i; // 从左向右找第一个大于x的数if(i j)a[j--] a[i];}a[i] x;quickSort(a, l, i-1); /* 递归调用 */quickSort(a, i1, r); /* 递归调用 */}
}int main()
{int i;int a[] {30,40,60,10,20,50};int ilen (sizeof(a)) / (sizeof(a[0]));cout before sort:;for (i0; iilen; i)cout a[i] ;cout endl;quickSort(a, 0, ilen-1);cout after sort:;for (i0; iilen; i)cout a[i] ;cout endl;return 0;
}
java实现
/*** 快速排序Java** author skywang* date 2014/03/11*/public class QuickSort {/** 快速排序** 参数说明* a -- 待排序的数组* l -- 数组的左边界(例如从起始位置开始排序则l0)* r -- 数组的右边界(例如排序截至到数组末尾则ra.length-1)*/public static void quickSort(int[] a, int l, int r) {if (l r) {int i,j,x;i l;j r;x a[i];while (i j) {while(i j a[j] x)j--; // 从右向左找第一个小于x的数if(i j)a[i] a[j];while(i j a[i] x)i; // 从左向右找第一个大于x的数if(i j)a[j--] a[i];}a[i] x;quickSort(a, l, i-1); /* 递归调用 */quickSort(a, i1, r); /* 递归调用 */}}public static void main(String[] args) {int i;int a[] {30,40,60,10,20,50};System.out.printf(before sort:);for (i0; ia.length; i)System.out.printf(%d , a[i]);System.out.printf(\n);quickSort(a, 0, a.length-1);System.out.printf(after sort:);for (i0; ia.length; i)System.out.printf(%d , a[i]);System.out.printf(\n);}
}
上面3种语言的实现原理和输出结果都是一样的。下面是它们的输出结果 before sort:30 40 60 10 20 50
after sort:10 20 30 40 50 60