C++快速排序实现

本文系转载,出处:https://segmentfault.com/a/1190000002651247

今天看到 V2EX 上有人讨论 社招还会问 “请手写选择排序算法” 吗,看来还是有很多人关心的。结合自己最近面试的经历,我可以明确的告诉大家,类似这种问题,只要你的工作经验小于 10 年,基本上逃不掉。劝大家不如抽点时间早做准备。

面试中遇到问快排的,如上面那个帖子中的情况。你就可以上一份简式快排了,何谓简式?最短的代码表述快排的思想。

快速排序算法用白话说,就是从头到尾迭代,和支点比较,大的不管,小的换。换了才往后看。最后支点戳中间,算是分界线。

快排的思想,实质是分治法。基于什么来分?找一个支点来分,通常称之为 pivot, 而这个分的过程称之为 partition, 基于以上两点,我们用递归的方式描述快排:

void quicksort(vector<int> &vi, int l, int r) {
    if (l < r) {
        int pivot = partition(vi, l, r);
        quicksort(vi, l, pivot-1);
        quicksort(vi, pivot+1, r);
    }
}

如何?简单吧。有人说面试的时候手写快排,如果提前没有背下来的话,肯定歇菜。我不认为这样基础的算法是需要背的,上面这个递归,如此简洁,如此美,真的需要硬记?

有人说,这个好理解,关键在于 partition 如何实现。的确,partition 是快排的灵魂。CLRS 里采用了以尾巴为支点的策略,我在这里与其保持一致:

int partition(vector<int> &vi, int l, int r) {
    int k = l, pivot = vi[r];
    for (int i = l; i < r; ++i)
        if (vi[i] <= pivot) swap(vi[i], vi[k++]);
    swap(vi[k], vi[r]);
    return k;
}

完整代码整理:

#include <iostream>
#include <vector>
using namespace std;

int partition(vector<int> &vi, int l, int r) {
    int k = l, pivot = vi[r];
    for (int i = l; i < r; ++i)
        if (vi[i] <= pivot) swap(vi[i], vi[k++]);
    swap(vi[k], vi[r]);
    return k;
}

void quicksort(vector<int> &vi, int l, int r) {
    if (l < r) {
        int pivot = partition(vi, l, r);
        quicksort(vi, l, pivot-1);
        quicksort(vi, pivot+1, r);
    }
}

int main()
{

    int a[] = {3,5,7,9,2,3,1,0,7,5,4};
    vector<int> va(a, a+11);//array转vector

    cout<<"Before quicksort:\n";
    for(int x:va)
        cout<<x<<" ";
    cout<<endl;
    cout<<"After quicksort:\n";
    quicksort(va, 0, va.size() - 1);

    for(int x:va)
        cout<<x<<" ";

    return 0;
}

猜你喜欢

转载自blog.csdn.net/xiangxianghehe/article/details/82458589
今日推荐