C语言和快速排序以及一些想法

#include<stdio.h>

int quick_sort(int num[], int left, int right);

int main(){
    int li[] = {8,12,5,9,2,11,28,1,9,};
    int n = sizeof(li)/sizeof(li[0]);

    quick_sort(li,0,n-1);

    int i;
    for (i = 0;i<n;i++){
        printf("数组第%d个数是%d\n",(i+1),li[i]);
    }
    return 0;
}

int quick_sort(int num[], int left, int right){
    if (right <= left){
        return 0;
    }

    int std = num[left];
    int i = left;
    int j = right;
    int temp;

    while(j > i){
        while(j>i){
            if(num[j] >= std){
                j --;
            }else{
                num[i] = num[j];
                num[j] = std;
                break;
            }               
        }
        while(j > i){
            if(num[i] < std){
                i++;
            }else{
                num[j] = num[i];
                num[i] = std;
                break;
            }
        }
    }

    quick_sort(num,left,i);
    quick_sort(num,i+1,right);
}

有价值的思考在用python实现快速排序后基本上都说了,C语言也没什么好说的了。
时隔多日再次复现快速排序,一开始卡在怎么让小于基准数的在一端,大于基准数的在一端。

我错误的思路:单纯从一侧比。。
比如说 8 9 10 4 5;
把8当做基准数,5比8小,则把5和8交换位置:5 9 10 4 8;
然后4和8比,又小,则再交换位置5 9 10 8 4;
10,9比8大,不动。。
然后又轮到5,最后变成了 8 9 10 5 4。。。。

正确的想法是,既然不要求较大组中是有序的,也就是最右边的最大,那只要遇到比基准数大的,就放到最右边。再朋友一个,放次右边。较小组同理啊,只要碰到一个小的,就放到最左边,再碰到一个,放到第二位。最后就会把基准数夹到了中间。
而由于把最左边的数保存在了基准数中,结合挖坑思想,应该先找比它小的。
而这个比它小的,为何是从右边找起呢?因为如果右边第一个数比基准数大,那没事儿,不懂它;或者看做原地挖坑原地埋,然后继续向前找,假设倒数第二个比基准数小了,那就可以把它放到之前的那个坑中。你想,那倒数第二个数的值已经到了之前的坑里,它本身的位置就是一个坑了呀!这时候就又要找比基准数大的数去填充,然后再从左边开找,找到一个比它小的去填充,这样左边又多了一个可以用来填从右边找到的较小的数的坑~~这样就形成了良性循环,最后两边就会在一个位置上撞上,从左边找小的超过位置,碰到的都是比基准数大的,从右边找大的超过这个位置,又都是小的。那这个位置就用来放基准数啦。
不过我这里漏掉了等于的情况,这个必须被左边找过来或者右边找过去的一个考虑。否则可能会陷入死循环。

而如果说把最左边的数当做基准数,从左边找起,首先要放在最左边嘛,那肯定还要找一个比它小的。假设数0(坑0)是左边第一个数,作为基准数它的值已经在std或者temp或者什么变量里了,所以可以填入其他东西。从左边找起,假设数1比数0大,数2比数0小,那数2的值填到坑0里面,它自己变成了坑1。然而,此时基准数的位置应该在数0和数1之间了,请问要怎么样才可以在数0和数1里面凭空挖出一个坑?这就必须把整组数据后移一个坑。。。所以这样做是要不得的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值