冒泡排序及快速排序实现

各位码友身为软件开发工程师,算法中的排序可谓是重重之重,那么今天小码哥就给大家带来两种交换排序,简单算法中的冒泡排序,和号称排序算法中的王者快速排序,是不是很期待呀大笑大笑,话不多说,码代码啦!!!


冒泡排序

先给大家介绍一下什么是冒泡排序?
冒泡排序 (Bubble Sort)是一种交换排序。
它的基本思想是 : 两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止。

说了这么多,还是不太懂是什么? 那么重点来啦–》

//对传入的arr数组进行排序,数组长度为len
void BubbleSort(int *arr, int len)
{
    int i,j;
    for(i=0; i<len-1; ++i) //外层循环控制冒泡次数
    {
        for(j=0; j<len-i-1; ++j)//内存循环控制交换次数
        {
            if(arr[j] > arr[j+1])
            {
                swap(&arr[j],&arr[j+1]);
                //自己实现交换函数,记住一定要传地址,swap函数要用指针接收,否则值传递不能达到两个数值交换的结果
            }
        }
    }
}

以上就是小码哥实现的冒泡排序,不得不说,这代码小码哥都不好意思交给漂亮的HR小姐姐,因为HR小姐姐要效率高的排序,很显然上述排序不能满足。那就再来个优化版的吧。

冒泡排序优化版

void BubbleSort(int *arr, int len)
{
    int i,j;
    int flag = true;//加一个标志位,优化冒泡排序,提高效率
    for(i=0; i<len-1; ++i)
    {
        flag = false;
        for(j=0; j<len-i-1; ++j)
        {
            if(arr[j] > arr[j+1])
            {
                flag = true;
                swap(&arr[j],&arr[j+1]);
            }
        }
        if(flag == false)
        {
            break;
        }
    }
}
//代码改动的关键就是在i变量的for循环中,增加了对flag是否为true的判断,经过这样的改进,冒泡排序在性能上就有了一定提升,可以避免因已经有序的情况下的无意义循环判断。

冒泡排序改好了,拿给HR小姐姐看,小姐姐说还不错,就是处理大数据是还是不够,时间复杂度为O(N2),根本不能满足,那怎么办呢,小码哥只能拿出自己的看家本领了,请出算法中的王者,快速排序,希望能讨小姐姐的欢心。


快速排序

/*那么什么是快排呢?
快速排序(Quick Sort)的基本思想 :通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的。*/

void QuickSort(int *arr, int low, int high)
{
    if (low > high)
        return;
    int first = low;
    int last = high;
    int key = arr[first];//将第一个值作为枢纽值
    while(first < last)//从表的两端向中间扫描
    {
        while(first < last && arr[last] >= key)
            --last;
        arr[first] = arr[last];//将第一个比key小的值移到低端,采用赋值而不是交换的方式进行操作

        while(first < last && arr[first] <= key)
            ++first;
        arr[last] = arr[first];//将第一个比key大的值移到高端,采用赋值而不是交换的方式进行操作
    }
    arr[first] = key;//枢纽记录到位
    QuickSort(arr,low,first-1);//递归小端
    QuickSort(arr,first+1,high);//递归大端
} 

我把快排写好了,拿给HR小姐姐,小姐姐非常开心,问我还能优化吗?万一我取的枢轴是最大值或最小值呢,那这个算法不就连冒泡排序都不如了吗?为了小姐姐能更开心,快排的优化版本来啦–》


快速排序优化版

void QuickSort(int *arr, int low, int high)
{
    while(low > high)
        return;
    int first = low;
    int last = high;
    int m = last / 2; //计算数组中间的元素下标
    if(arr[first] > arr[last])
        swap(&arr[first],&arr[last]);//交换左端和右端的值,保证左端较小
    if(arr[m] > arr[last])
        swap(&arr[m],&arr[last]);//交换中间和右端的值保证中间较小
    if(arr[m] > arr[first])
        swap(&arr[m],&arr[first]);//交换中间和左端的值,保证左端为三值之间
    int key = arr[first];//用数组里面的第一个值作为枢纽,第一个值为三数去中法所得到的

    while(first < last)//从数组两端交替扫描
    {
        while(first < last && arr[last] >= key)
            --last;
        arr[first] = arr[last];

        while(first < last && arr[first] <= key)
            ++first;
        arr[last] = arr[first];
    }
    arr[first] = key;
    QuickSort(arr,low,first-1);
    QuickSort(arr,first+1,high);
}

以上便是快排优化代码
快排优化思想:
1,三数取中法 : 取三个关键字先进行排序,将中间数作为枢轴,一般取左端,右端,中间三个数。
2,九数去中法 它先从这三个中数中分三次取样,每次取三个数,三个样品各取出中数,然后从这三个中数当中再取一个中数作为枢轴,这个有兴趣的码友可以自己实现哦。
3,优化不必要的交换。

快排的时间复杂度是O(nlogn),这下HR小姐姐应该就满意啦,看着HR小姐姐满面笑容,小码哥也该回家睡觉了。

码完,收工

你可能感兴趣的:(排序算法)