快速排序
2017-06-02 17:47
218 查看
快速排序也是交换排序的一种。
快速排序的基本思想是,通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
假设待排序的记录序列为{r[low],r[low +1 ],r[low +2],.....r[high]},首先在该序列中任意选择一个记录(该记录成为支点,通常选r[low]作为支点),然后将所有关键字比支点小的记录都放在支点的左边,将所有关键字比支点大的记录放到支点的右边,由此可以将该支点最后所落的位置i作为分界线,将记录{r[low],r[low
+1 ],r[low +2],.....r[high]}分割为两个部分{r[low],r[low +1 ],r[low +2],.....r[i-1]}和{r[i+1],r[i+2]........r[high]},这个过程称为一次划分(一趟快速排序)。通过一趟快速排序,支点记录就落在了最终排序结果的位置上了。
一趟快速排序的步骤如下:
(1)设置两个变量i和j,初值分别为low和high,分别表示待排序序列的起始下标和终止下标。
(2)将第i个记录设置成为支点,将关键字值暂存在变量pivot中,即pivot = r[i]。
(3)从下标为j的位置开始从后向前依次搜索,当找到第一个比pivot小的记录时,将该记录复制到下标为i的位置上,然后i=i+1。
(4)从下标为i的位置起向后依次搜索,当找到比pivot大的记录时,将该记录复制到下表为j的位置上,再令j=j-1。
(5)重复(3)、(4)步骤,直到i==j为止。
(6)将pivot置于最终位置,r[i] = pivot。
一趟快排划分的代码如下:
算法性能分析:
(1)空间复杂度:快速排序在系统内部需要一个栈来实现递归,每层递归调用的指针和参数均需要用栈来存放。快速排序的递归过程可以用一棵二叉树来表示。若每次划分较为均匀,则其递归树的高度为O(logn),故所需栈空间为O(logn),最坏情况下,即递归树为一个单枝树,书的高度为O(n),其空间复杂度为O(n)。
(2)时间复杂度:在含有n个记录的排序序列中,每进行一次划分需要进行n此比较,时间复杂度为O(n)。最好情况下,每次划分正好是两个等长的子序列,T(n) <=cn +2T(n/2),即T(n)<= cnlogn + nT(1)=O(nlogn)。最坏情况下,当关键字序列有序或者基本有序,在快速排序过程中每次划分只能得到一个子序列,这样快速排序反而退化为冒泡排序,时间复杂度为O(n^2)。
快速排序是不稳定的排序算法。
快速排序的基本思想是,通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
假设待排序的记录序列为{r[low],r[low +1 ],r[low +2],.....r[high]},首先在该序列中任意选择一个记录(该记录成为支点,通常选r[low]作为支点),然后将所有关键字比支点小的记录都放在支点的左边,将所有关键字比支点大的记录放到支点的右边,由此可以将该支点最后所落的位置i作为分界线,将记录{r[low],r[low
+1 ],r[low +2],.....r[high]}分割为两个部分{r[low],r[low +1 ],r[low +2],.....r[i-1]}和{r[i+1],r[i+2]........r[high]},这个过程称为一次划分(一趟快速排序)。通过一趟快速排序,支点记录就落在了最终排序结果的位置上了。
一趟快速排序的步骤如下:
(1)设置两个变量i和j,初值分别为low和high,分别表示待排序序列的起始下标和终止下标。
(2)将第i个记录设置成为支点,将关键字值暂存在变量pivot中,即pivot = r[i]。
(3)从下标为j的位置开始从后向前依次搜索,当找到第一个比pivot小的记录时,将该记录复制到下标为i的位置上,然后i=i+1。
(4)从下标为i的位置起向后依次搜索,当找到比pivot大的记录时,将该记录复制到下表为j的位置上,再令j=j-1。
(5)重复(3)、(4)步骤,直到i==j为止。
(6)将pivot置于最终位置,r[i] = pivot。
一趟快排划分的代码如下:
public int partition(int[] array, int start, int end) { int i = start; int j = end; int temp = 0; if (i < j) { temp = array[i]; while (i != j) { while (array[j] > temp && i < j) { j--; } if (i < j) { array[i] = array[j]; i++; } while (array[i] < temp && i < j) { i++; } if (i < j) { array[j] = array[i]; j--; } } array[i] = temp; } return i; }
public static void qSort(int[] arr, int start, int end) { if (start < end) { int pivot = partition(arr, start, end); qSort(arr, start, pivot - 1); qSort(arr, pivot + 1, end); } }
算法性能分析:
(1)空间复杂度:快速排序在系统内部需要一个栈来实现递归,每层递归调用的指针和参数均需要用栈来存放。快速排序的递归过程可以用一棵二叉树来表示。若每次划分较为均匀,则其递归树的高度为O(logn),故所需栈空间为O(logn),最坏情况下,即递归树为一个单枝树,书的高度为O(n),其空间复杂度为O(n)。
(2)时间复杂度:在含有n个记录的排序序列中,每进行一次划分需要进行n此比较,时间复杂度为O(n)。最好情况下,每次划分正好是两个等长的子序列,T(n) <=cn +2T(n/2),即T(n)<= cnlogn + nT(1)=O(nlogn)。最坏情况下,当关键字序列有序或者基本有序,在快速排序过程中每次划分只能得到一个子序列,这样快速排序反而退化为冒泡排序,时间复杂度为O(n^2)。
快速排序是不稳定的排序算法。
相关文章推荐
- 数据结构9:快速排序
- java排序算法1 快速排序
- 快速排序
- Java算法快速排序
- 排序算法系列-交换之快速排序
- 快速排序Java实现--最简单的实现方法
- 排序算法(五)——快速排序
- 内部排序系列 之 冒泡排序与快速排序
- 快速排序详解--C语言实现
- #排序算法#【4】快速排序
- 快速排序解析
- 快速排序java实现(基础)
- 大规模草地的快速绘制排序
- Win10系统调整快速访问文件夹顺序按照访问时间来排序
- 快速排序-Java-随机算法
- 快速排序
- 第十五周 项目1 快速排序
- java 快速排序随机选择key
- 选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、归并排序和基数排序
- <assignment5>链表快速排序