快速排序:手撕代码就能征服的经典算法(内附超详细图解)

一、从图书馆乱架说开去

最近帮学校整理图书馆时(别问为啥程序猿要干这个),发现管理员大爷的排序方式堪称"行为艺术"——他居然把《C++ Primer》插在《Java编程思想》和《Python从入门到放弃》之间!这种"即兴创作"式的排序方式,让我深刻理解了一个真理:没有算法的世界,注定是混乱的!(说人话:快排真的超重要啊!)

二、快速排序的精髓:分而治之的艺术

快速排序的精妙之处,就像把大象装冰箱分三步:

  1. 找基准:随便挑本书当分界线(专业术语叫pivot)
  2. 搞事情:把比它薄的书放左边,厚的放右边(专业术语叫partition)
  3. 玩递归:对左右两堆书重复以上操作

(偷偷告诉你)这个算法的发明者Tony Hoare当年在莫斯科交流时,居然是在给俄语词典排序时想到这个点子的!所以说,生活中处处是算法啊~

三、手把手实现经典快排(C语言版)

// 关键函数:分区操作
int partition(int arr[], int low, int high) {
    int pivot = arr[high];  // 选最后一个元素当基准
    int i = (low - 1);     // 小于基准的边界指针

    for (int j = low; j <= high - 1; j++) {
        if (arr[j] < pivot) {
            i++;
            // 交换操作
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }
    // 把基准放到正确位置
    int temp = arr[i+1];
    arr[i+1] = arr[high];
    arr[high] = temp;
    return i + 1;
}

// 递归函数本体
void quickSort(int arr[], int low, int high) {
    if (low < high) {
        int pi = partition(arr, low, high);
        // 左右开弓递归处理
        quickSort(arr, low, pi - 1);
        quickSort(arr, pi + 1, high);
    }
}

(代码小贴士)这个版本虽然经典,但有个致命弱点——如果数组本来就是有序的,时间复杂度会退化到O(n²)!别急,后面教你怎么优化。

四、时间复杂度揭秘:从O(n²)到O(n log n)的蜕变

先上结论(快拿小本本记好):

场景时间复杂度出现概率
最佳情况O(n log n)日常使用
最差情况O(n²)需要规避
平均情况O(n log n)普遍存在

(敲黑板)这里要注意啦!快排的性能完全取决于基准的选择质量。就像找对象,选对pivot天天过情人节,选错了…你懂的~

五、三大优化秘籍(面试加分项)

1. 三数取中法

// 在low, high, mid三个位置取中间值
int median_of_three(int arr[], int low, int high) {
    int mid = low + (high - low)/2;
    // 三数比较的骚操作
    if (arr[low] > arr[mid]) swap(&arr[low], &arr[mid]);
    if (arr[low] > arr[high]) swap(&arr[low], &arr[high]);
    if (arr[mid] > arr[high]) swap(&arr[mid], &arr[high]);
    return mid;
}

2. 尾递归优化

把第二个递归调用改为循环,栈深度从O(n)降到O(log n),防止堆栈溢出!

3. 插入排序混合使用

当子数组长度小于10时切换成插入排序,实测速度提升20%+

六、快排的十八般武艺

你以为快排只能排数字?Too young!

  • 字符串排序:按字典序排列
  • 对象排序:根据指定属性排序
  • 多关键字排序:先按姓名再按年龄
  • 大数据处理:外排序的基石

(冷知识)Linux系统的sort命令底层就是快排的优化版!下次用sort命令时,可以自豪地说:“这算法我懂!”

七、算法选择困难症的解药

什么时候该用快排?记住这个口诀:

数组较大选快排
数据随机更痛快
内存紧张要慎用
稳定需求请走开

(说人话)数据量大且随机分布时首选快排,需要稳定排序时请选择归并排序。

八、从快排看人生哲学

最后来个程序员式鸡汤:

  1. 学会取舍:像选择pivot一样抓住关键
  2. 分治思维:大问题拆成小问题逐个击破
  3. 递归精神:把复杂交给递归,把简单留给自己
  4. 持续优化:没有最好的算法,只有更适合的场景

下次面试被问快排,记得微笑说出:“这个算法啊,它教会了我…”(面试官眼睛会发光你信不信?)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值