数据结构学习笔记(15)---交换类排序

来源:互联网 发布:好听的淘宝会员名大全 编辑:程序博客网 时间:2024/06/10 21:56
交换类排序其实一般就两种,一个就是冒泡排序,另一个就是快速排序,比较两张算法,肯定是快排效率较高,原因很简单,对于冒泡排序只能与相邻的元素进行比较,互换时候只能消除一个逆序,但是快排通过两个不相邻的元素交换,可以消除待排序记录中的多个逆序,即后面的元素不需要再做无谓的逆序了。
(1)冒泡排序比较简单,简单说下算法思路:
过程:

a. 从第一个记录开始和第二个记录比较,如果大于第二个记录就交换,否则就不交换,比较下一个元素,依次循环下去,因此第一趟就会找到最大的值放到数组的最后面n-1的位置上。
b. 然后用相同的方式在前n-2个元素中得出最大值放在n-2位置。
c. 重复上述操作,知道全部比较完成。

void BullSort(int a[], int length){    for (size_t i = 0; i < length - 1; i++)    {        for (size_t j = 0; j < length-1-i; j++)        {            if (a[j] > a[j + 1])            {                swap(a[j], a[j + 1]);            }        }    }}
性能分析: T(n) = O( n ^2),k空间复杂度 S(n) = O(1)
(2)快速排序:该算法是有英国的计算机学家Hore提出的,对于个人来说非常喜欢快速排序,不仅仅因为是其算法效率比较高,最主要的原因还是他的这种思想很好,值得借鉴,。

算法思路:
a. 首先需要需要设置两个人标志位:low,high来记录数组的头和末尾,并取第一个节点作为基准a[low]保存在临时变量a[0]中.
b. 然后从有右向左依次寻找第一个小于a[0]的值,然后放在a[low]中,此时low++;
c. 然后从有low向右依次寻找第一个大于a[0]的值,然后放在a[high]中,此时high++;
d. 依次循环知道high== low循环结束。把a[0放在a[high]中。
e. 至此第一趟排序结束,找到分支点,此时把数组分为两部分,然后分对左右两部分进行上述操作,最后排序完成。
例如:
这里写图片描述

代码如下:

int QKPass(int a[], int low, int high){    a[0] = a[low];    while (low < high)    {        //从右寻找第一个小于a[0]得数        while ( high > low && a[high] > a[0])        {            high--;        }        if (high > low)        {            a[low] = a[high];            low++;        }        //从左寻找第一个大或等于于a[0]得数        while (high > low && a[low] < a[0])        {            low++;        }        if (high > low)        {            a[high] = a[low];            high--;        }    }    a[low] = a[0];    return low;}void QKSort(int a[],int low,int high){    if (low < high)    {        int pos = QKPass(a, low, high);//找到分支点        QKSort(a,low, pos - 1);        QKSort(a, pos+1, high);    }}
性能分析: T(n) = O( nlog2(n)),k空间复杂度 S(n) = O(1)
小结:
排序算法 时间复杂度 最好情况 最坏情况 空间复杂度 稳定性 冒泡排序 O(n^2) O(n) O(n^2) O(1) 稳定 快速排序 O(nlog2(n)) O(nlog2(n)) O(n^2) S(n)=O(log2(n))最坏情况:S(n)=O(n) 不稳定
原创粉丝点击