排序算法(快速排序、堆排序、归并排序)

排序算法

  各种排序算法的平均时间复杂度和最好最坏情况,空间复杂度如图所示,本文主要总结下常用的效率高的三种排序算法,分别是快速排序,归并排序和堆排序。
在这里插入图片描述

快速排序

  快排是基于分治的思想去实现的,每次找到中间的数据,再根据中间的数据分别排序左右两边,使得左边的数都小于(或大于)右边的数,然后再递归进入下一层循环去继续比较,具体实现代码如下所示:

void quick_sort(int a[], int l, int r){
    if(l >= r) return;
    int i = l - 1, j = r + 1, x = a[l + r >> 1];
    while(i < j){
        do i ++; while(a[i] < x);//do while是while中为真就继续执行,为假就退出。
        do j --; while(a[j] > x);
        if(i < j) swap(a[i], a[j]);
    }
    quick_sort(a, l, j); quick_sort(a, j + 1, r);
}

归并排序

  归并排序也是基于分治的思想,使用数组中心位置来划分,分成最少最小的组合后再把左右两边分别和中间值比较,用一个新的数组去存取新排列后的数据,具体实现如下所示:

void merge_sort(int q[], int l, int r)
{
    if (l >= r) return;

    int mid = l + r >> 1;
    merge_sort(q, l, mid);
    merge_sort(q, mid + 1, r);

    int k = 0, i = l, j = mid + 1;
    while (i <= mid && j <= r)
        if (q[i] <= q[j]) tmp[k ++ ] = q[i ++ ];
        else tmp[k ++ ] = q[j ++ ];

    while (i <= mid) tmp[k ++ ] = q[i ++ ];
    while (j <= r) tmp[k ++ ] = q[j ++ ];

    for (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];
}

堆排序

  堆可以想象成是一个完全二叉树,一般都会直接使用STL中的模板,在STL中的堆就是优先队列,下面代码分别为小根堆和大根堆还有重构的使用方法:

priority_queue<pair<int, int>> a//这个默认就是用大根堆的方式排序,从大到小,堆顶元素为大
priority_queue<pair<int, int>, vector<pair<int, int>> greater<pair<int, int>>> b//这个就是用小根堆的方式排列,从小到大,堆顶元素为小
//重构的写法
    class  mycompare{
        public:
        	bool operator()(const pair<int, int>& a, const pair<int, int>& b){
                if(a.first == b.first)			//这里实现的效果是按照第一个元素的大小从大到小排列,小的在最上面
                    return a.second > b.second; //如果第一个元素相等就按照第二个元素排列,从大到小排列,小的在最上。
                return a.first > b.first;
            }
    }
//重构完成之后这样使用:
priority_queue<pair<int, int>, vector<pair<int, int>>, mycompare> heap;

sort函数

  sort并不是简单的快速排序,它对快速排序进行了优化。此外,它还结合了插入排序和推排序。系统会根据数据形式和数据量自动选择合适的排序方法。它每次排序中不只选择一种方法,比如给一个数据量较大的数组排序,开始采用快速排序,分段递归,分段之后每一段的数据量达到一个较小值后它就不继续往下递归,而是选择插入排序(插入排序的基本思想是每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子文件中的适当位置,直到全部记录插入完成为止),如果递归的太深,他会选择推排序。

vector<int> nums;
sort(nums.begin(), nums.end());//升序
sort(nums.end(), nums.begin());//降序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值