【一个小实验】排序效率比较

最近参加内推,四轮技术面里头有三轮都问到了排序(各种排序)。无奈表示我还没复习数据结构和算法部分.....今天正好有空,把几个被问到的排序算法都写出来比较下到底哪个更快,快多少。
        需要注意的是:两路归并排序这个O(NlogN)时间复杂度的我没(Bu)写(Hui)。原因在快速排序里面已经展现了。其次,每次参与的数组均由随机函数生成。

        先说结论:
        1、快排名副其实的“快”,在不发生递归栈溢出的情况下速度惊人; 
        2、堆排序同学成绩稳定,在大数据量情况下,N^2的冒泡法同学哭晕在了厕所;
        
        下面是截图:
         
        1、测试数组长度为 1K的时候:
        图片 
        可以看到“快速排序”这个算法绝非浪得虚名啊 。当然,后面还有更猛的。
       

        2、 
测试数组长度为 5K的时候:
图片
     
  
        3、 
测试数组长度为 10K的时候:
图片
        Oh,My God!!! 一直以速度著称的快排同学终于因为短跑改成了长跑体力不支倒(stack)下(over)了(flow)。那么我们看看剩下两名选手的成绩吧。嗯,堆排序同学耗时依然只有冒泡法一半不到。那么接下来这两名选手就要参加本次实验的终极挑战了!
        
        终极挑战!!!
        4、 
测试数组长度为 50K的时候:
        图片
    
堆排序同学凭借稳定的发挥,一举夺魁。而 时间复杂度N^2的冒泡法同学耐力虽好,无奈速度实在不行,最后如龟爬一般的完成了比赛。最后用时是堆排序的2.94≈3倍。

    最后的最后,翠花,上代码:

    

/*
因为用了模板类。我用了一个mysortalgrithm.h单独存放这些排序算法
*/
#pragma once
#include <iostream>
#include <string>
template<typename T>
class MySortAlgrithm
{
public:
    /*
        冒泡法排序
    */
    static void bubbleSort(T* a, size_t length)
    {
            int i = 0;
            int j = length - 1;
            for (j = length - 1; j>0; j--)//从最后一个数开始。J标记了已经排好序的数组部分,直到J==0;表明整个数组都已经排序完毕了
                for (i = 0; i < j; i++)//从第一个数开始。I标记了被考察的数
                {
                    if (a[i]>a[i + 1])
                    {
                        mySwap(a[i], a[i + 1]);
                    }
                }
    }
    /*
        小根堆排序
    */
    static void minHeapSort(T* a, size_t length)
    {
        int tempLength = length;
        for (int i = 0; i < tempLength; i++)
        {
            minHeapify(a, length - i);
            //将最小值放进数组中已经排序的部分
            mySwap(a[0],a[length-i-1]);
        }
        
    }
    /*
        快速排序的调用接口
    */
    static void fastSort(T*a, size_t length)
    {
        subFastSort(a,0,length-1);
    }
private:
    
    /*
    真正的快速排序,被包装在一个fastSort(T* a, size_t length)中
    */
    static void subFastSort(T* a, int from, int to)
    {
        if (to < from)
            return;
        int i = from;
        int j = to;
        T temp = a[from];
        while (i < j)
        {
            //最开始从右侧向左查找第一个
            while ( i < j && a[j]>=temp)
                j -= 1;
            //注意,这个i<j判断很重要
            if (i < j)
            {
                a[i] = a[j];//将小于temp的值移动到temp的左边
                i += 1;
            }
            while (i < j && a[i]< temp)
                i += 1;
            if (i < j)
            {
                a[j] = a[i];//将大于temp的值移动到temp的右边
                j -= 1;
            }
        }
        a[i] = temp;
        subFastSort(a,from,i-1);
        subFastSort(a,i+1,to);
    }
    /*
        将数组调整为小根堆
        a:被调整的数组(乱序堆)
        length:数组长度(堆大小)
        startPos:从哪个位置开始调整堆
    */
    static void minHeapify(T* a,size_t length)
    {
        //-----------------------------------------------------------------
        //--前方高能预警:堆调整的时候必须从“叶节点”开始"向上"调整!!!---
        //-----------------------------------------------------------------
        for (int i = length-1; i >=0 ; i--)
        {
            size_t lChild = i * 2 + 1;
            size_t rChild = i * 2 + 2;
            //如果没有左子树,自然就没有没有右子树,那就不用检查这个点是否满足堆的性质了
            if (lChild > length-1)
                continue;
            
            size_t  lessPos;//左右子树中较小的那个数
            //如果左子树存在,但右子树不存在
            if (lChild <= length - 1 && rChild > length - 1)
                lessPos = lChild;
            //如果这个点比它的左右子树中较小的那个大,就互换
            else if (lChild <= length - 1 && rChild <= length - 1)
                lessPos= a[lChild] > a[rChild] ? rChild : lChild;
            if (a[i]>a[lessPos])
                mySwap(a[i],a[lessPos]);
        }
    }
    /*
        交换两个数
    */
    static void mySwap(T& a, T& b)
    {
        T temp = a;
        a = b;
        b = temp;
    }
};
/*
---------------------------------------主函数-----------------------------------------
*/
#pragma once
#include <iostream>
#include <string>
#include <ctime>
#include "MySortAlgrithm.h"
using namespace std;
#define ARRAY_LENGTH 5000
int main()
{
    int a[ARRAY_LENGTH];
    for (int i = 0; i < ARRAY_LENGTH; i++)
    {
        a[i] = rand()%100;
    }
    
    int length = end(a) - begin(a);
    clock_t start_time = clock();
    {
        MySortAlgrithm<int>::bubbleSort(a,length);
    }
    clock_t end_time = clock();
    std::cout << "冒泡法耗时: " <<static_cast<double>(end_time - start_time) / CLOCKS_PER_SEC * 1000 << "ms" << endl;//输出运行时间
    
    
    clock_t start_time2 = clock();
    {   
        MySortAlgrithm<int>::minHeapSort(a, length);
    }
    clock_t end_time2 = clock();
    std::cout << "堆排序耗时: " <<static_cast<double>(end_time2 - start_time2) / CLOCKS_PER_SEC * 1000 << "ms" << endl;//输出运行时间
    
    clock_t start_time3 = clock();
    {
        MySortAlgrithm<int>::fastSort(a, length);
    }
    clock_t end_time3 = clock();
    std::cout << "快排耗时: " <<static_cast<double>(end_time3 - start_time3) / CLOCKS_PER_SEC * 1000 << "ms" << endl;//输出运行时间
    return 0;
}

    收工~


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值