快速排序 归并排序
2015-07-22 21:58
169 查看
快速排序 归并排序
大神如此之多的世上,我等小渣如何生存。1. 归并排序
许多算法在结构上是递归的,为了解决一个给定的问题,算法一次或多次递归地调用其自身以解决紧密相关的若干子问题,这些算法典型地遵循分治法的思想。分治模式在每层递归时都有3个步骤:
分解原问题为若干子问题,这些子问题是原问题的规模较小的实例。
解决解决这些子问题,递归地求解各个子问题。然而,若子问题的规模最够小,则直接求解。
合并这些子问题的解成原问题的解。
归并排序算法完全遵循分治模式。直观上其操作如下:
分解:分解待排序的n个元素的序列成各具有n/2个元素的两个子序列。
解决:使用归并排序递归地排序两个子序列。
合并:合并两个已排序的子序列以产生已排序的答案。
过程:将待排序的n个元素的序列,分为两个长度n/2的子序列,两个子序列递归调用归并排序,排序好后,再合并两个子序列。
/* * 将有二个有序数列a[first...mid]和a[mid+1...last]合并 * 在函数外申请一个临时数组作为参数传递,避免递归不断创建临时数 * 组的开销 * 如果不用临时数组,每次递归都分配临时数组,注意数组长度最大。 */ void mergearray(int a[], int first, int mid, int last, int temp[]) { int i = first, j = mid + 1; int m = mid, n = last; int k = 0; while (i <= m && j <= n) { if (a[i] < a[j]) temp[k++] = a[i++]; else temp[k++] = a[j++]; } while (i <= m) temp[k++] = a[i++]; while (j <= n) temp[k++] = a[j++]; for (i = 0; i < k; i++) a[first + i] = temp[i]; } void mergesort(int a[], int first, int last, int temp[]) { if (first < last) { int mid = (first + last) / 2; mergesort(a, first, mid, temp); //左边有序 mergesort(a, mid + 1, last, temp); //右边有序 mergearray(a, first, mid, last, temp); //再将二个有序数列合并 } }
用一个临时数组来保存暂时的排序好的结果。
归并排序的最好、最坏、平均的时间复杂度都是O(nlogn),且由于归并排序在归并过程中需要与原始记录序列同样数量的存储空间存放归并结果以及递归时深度为logn的栈空间,因此空间复杂度为O(n+logn)。归并排序是稳定的排序算法。
总之,归并排序是一种比较占用内存,但却效率高且稳定的算法。
2. 快速排序
2.1 快速排序的算法思想
快速排序,与归并排序相同,也使用了分治思想。一个典型的子数组A[p……r]进行快速排序的三步分治过程。分解:划分过程,数组A[p……r]被划分为两个子数组A[p……q-1]和A[q+1……r],使得A[p……q-1]中的每一个元素都小于等于A[q],而A[q]也小于等于A[q+1……r]中的每个元素,其中计算小标q也是划分过程的一部分。
解决:通过递归调用快速排序,解决分解后的两个子数组,对子数组A[p……q-1]和A[q+1……r]进行排序。
合并:因为子数组都是原址排序的,所以不需要合并操作,数组A[p……r]已经有序。
算法的关键部分是partition过程,它实现了对子数组A[p……r]的原址重排。
2.2 快速排序的性能分析
快速排序的运行时间依赖于划分是否平衡,而平衡又依赖于划分的元素。如果划分是平衡的,那么快速排序算法性能与归并排序一样。如果划分不平衡的,那么快速排序的性能接近于插入排序。最坏的情况下:划分产生的两个子问题包含n-1个元素和0个元素时,最坏的情况发生(如当输入数组完全有序时,快速排序的时间复杂度是O(N^2));
平均时间复杂度:O(nlogn)。
最坏的情况下时间复杂度是O(n^2)。虽然快速排序最坏情况时间复杂度很差,但是因为它的平均性能非常好,依然是实际排序应用中最好的选择。
快速排序不稳定。
参考:
[1] 算法导论 归并排序章节和快速排序章节
[2] http://blog.163.com/zhaohai_1988/blog/static/209510085201262245113372/
相关文章推荐
- 快速排序
- C#快速排序算法实例分析
- C++快速排序的分析与优化详解
- php简单实现快速排序的方法
- Java 快速排序(QuickSort)原理及实现代码
- 快速排序和分治排序介绍
- java 算法之快速排序实现代码
- Java实现快速排序算法(Quicktsort)
- Java中的数组排序方式(快速排序、冒泡排序、选择排序)
- C/C++实现快速排序的方法
- c语言实现冒泡排序、希尔排序等多种算法示例
- 深入单链表的快速排序详解
- C#使用委托实现的快速排序算法实例
- php实现快速排序的三种方法分享
- PHP两种快速排序算法实例
- 排序算法之PHP版快速排序、冒泡排序
- php排序算法(冒泡排序,快速排序)
- JavaScript实现快速排序(自已编写)
- Javascript快速排序算法详解
- JAVA算法起步之快速排序实例