交换排序

来源:互联网 发布:喝咖啡的利弊 知乎 编辑:程序博客网 时间:2024/04/30 14:21

交换排序共包含两种算法,冒泡排序和快速排序

一、冒泡排序

(Bubble Sort)是一种最简单的排序算法,将第一个记录和第二个记录的关键字进行比较,若为逆序,则进行交换,然后继续向后移动进行比较,以此类推,直至第n-1个记录和第n个记录的关键字进行过比较为止,这个过程称为第一趟冒泡排序。第二趟排序对前n-1个记录进行同样操作。

值得注意的是,冒泡排序的结束条件是“在一趟排序过程中没有进行过交换的操作”。

容易看出,若初始序列为“正序”,则只需要进行一趟排序,反之“逆序”的情况下,需要进行n-1趟排序,所以总的时间复杂度为O(n^2)


二、快速排序

(Quick Sort)是对冒泡排序的一种改进,基本思想是通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,分别排序。

选取一个枢纽pivotkey,通常选择第一个关键字,选择两个指针low和high,他们的初值分别为low和hign,则首先从high所指位置向前搜索找到第一个关键字小于pivotkey的记录和枢纽记录互相交换,然后从low所指位置起向后搜索,找到第一个关键字大于pivotkey的记录和枢纽记录互相交换,重复直到low=high为止。

Partition将序列一分为二,左面都比pivotkey小,右面都比pivotkey大,返回枢纽的位置。对两边分别进行快排,即Partition。

时间复杂度分析:平均时间为T(n)=k*n*ln^n,k为某个常数,在所有同数量级的现金排序方法中,快排的常熟因子k最小,因此就平均时间而言,快排是目前被认为是最好的一种内部排序方法。

平均时间复杂度O(n*logn)

当基本有序的时候,是冒泡排序,时间复杂度为O(n^2),所以为了改进他,通常在L[low],L[hign],L[(low+high)/2]三个数之间选择一个中间的数作为枢纽。

同冒泡排序,如果一个子序列没有进行交换,就没有必要对这个子序列进行排序了。

空间复杂度:快速排序需要一个栈空间来实现递归,如果每次都是均匀分割两个子序列,则栈的最大深度为(以2为底n的对数)+1,最坏情况下,栈的最大深度为n,如果每次都能先对长度短的子序列进行快速排序,栈的最大深度可以降低为O(logn)

测试:

int Partition(int L[], int low, int high){L[0] = L[low];int pivotkey = L[low];while (low < high){while (low < high && L[high] >= pivotkey)--high;L[low] = L[high];//此时high位置的数据比pivotkey的小,所以要放到low的位置while (low < high && L[low] <= pivotkey)++low;L[high] = L[low];}L[low] = L[0];return low;//枢纽位置}//主函数调用QSort(L, 1, L.length)void QSort(int L[], int low, int high){if (low < high){int pivotlocation = Partition(L, low, high);QSort(L, low, pivotlocation - 1);QSort(L, pivotlocation + 1, high);}}int main(){int L[] = {0, 49, 38, 65, 97, 76, 13, 27, 49};QSort(L, 1, 8);for (int i = 1; i <= 8; i++)cout << L[i] << endl;}


0 0
原创粉丝点击