快速排序算法

本文介绍了两种常见的排序算法——冒泡排序和快速排序。冒泡排序是一种简单的排序算法,通过重复遍历待排序的数列,交换相邻元素来逐步将数列按升序排列。而快速排序是对冒泡排序的优化,采用了分治策略,选取一个基准值,将数列分为两部分,左边小于基准,右边大于基准,然后分别对两部分进行排序,提高了效率。文中通过实例详细解释了快速排序的过程,并给出了相应的算法代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

冒泡排序

每次对相邻的两个数进行比较,类似于密码爆破一个个比对。显然比较浪费时间,且比较笨。

快速排序

冒泡排序的一种改进,也可以理解为多线程的冒泡排序

工作原理

在一串乱序数据中随机取一个值(一般代码实现都是取第一个值),然后对该数列进行分类,比随机值小的在随机值的左边,反之在右边

例子

[0x10, 0x37, 0x4f, 0x39, 0x3e ,0x39 ,0x13 ,0x2b ,0x4f ,0x8]进行排序,其中“●”表示取的随机值,“<”表示向左移动,“>”表示向右移动 “pivot”就是这个中间值,“left”表示当前排序的数据范围的始位置,“right”表示当前排序的数据范围的末位置

下面pivot=0x10 right=9 left=0即表示中间值为0x10,对该数据的0-9的索引值进行排序,以下为实现过程的部分数据

       ●                              							<
索引    0    1    2    3    4    5    6    7    8    9    pivot=0x10 right=9 left=0
数值   0x10 0x37 0x4f 0x39 0x3e 0x39 0x13 0x2b 0x4f 0x8
---------------------------------------------------------------
       ●    >                         							
索引    0    1    2    3    4    5    6    7    8    9    pivot=0x10 right=9 left=1
数值   0x8 0x37 0x4f 0x39 0x3e 0x39 0x13 0x2b 0x4f 0x37
---------------------------------------------------------------
//完成一次左边和右边的置换后,第二次while循环
       ●                             							
索引    0    1    2    3    4    5    6    7    8    9    pivot=0x10 right=8 left=1
数值   0x8 0x37 0x4f 0x39 0x3e 0x39 0x13 0x2b 0x4f 0x37
---------------------------------------------------------------
       ●                            						
索引    0    1    2    3    4    5    6    7    8    9    pivot=0x10 right=7 left=1
数值   0x8 0x37 0x4f 0x39 0x3e 0x39 0x13 0x2b 0x4f 0x37
---------------------------------------------------------------
       ●                            						          //....right : 7 -> 1
索引    0    1    2    3    4    5    6    7    8    9    pivot=0x10 right=1 left=1 
数值   0x8 0x10 0x4f 0x39 0x3e 0x39 0x13 0x2b 0x4f 0x37   // array[left] = pivot
---------------------------------------------------------------
//完成第一次递归函数  得到最小值0x8

                 ●                    							<
索引    0    1    2    3    4    5    6    7    8    9    pivot=0x4f right=9 left=2
数值   0x8 0x10 0x37 0x39 0x3e 0x39 0x13 0x2b 0x4f 0x37 
---------------------------------------------------------------
                 ●                    							
索引    0    1    2    3    4    5    6    7    8    9    pivot=0x4f right=9 left=3
数值   0x8 0x10 0x37 0x39 0x3e 0x39 0x13 0x2b 0x4f 0x37 
---------------------------------------------------------------
                 ●                    										//.....left : 3 -> 9
索引    0    1    2    3    4    5    6    7    8    9    pivot=0x4f right=9 left=9
数值   0x8 0x10 0x37 0x39 0x3e 0x39 0x13 0x2b 0x4f 0x4f 
---------------------------------------------------------------//得到最大值0x4f

//pivot=0x4f right=8 left=2,同样的方法对2-8中进行排序找到最大值

完整算法流程图

注意下面每个分支不代表一次while循环,这里简化为每次数列发生排序的结果

在这里插入图片描述

算法代码

    //假设要对数组的0-10位进行排序 L : 0  , R : 10
void info(int *array , int L , int R){
    if(L >= R) return;
    int left = L;
    int right = R;
    int pivot = array[left];
    while(left < right){
        while(right > left && array[right] >= pivot) right--;
        array[left] = array[right];
        while(left < right && array[left] <= pivot) left++;
        array[right] = array[left];
        if(left == right) array[left] = pivot; //完成左右指针合并
    }
    //上面就完成了对中间点的左右大小的分类
    info(array,L,left- 1);
    info(array,right+ 1,R);
}

测试代码

int main(){
    int array[10] = {0};

    int len = sizeof array / sizeof (int);
    srand(time(NULL));
    for (int i =0 ; i < len ; i++){
    ¦   array[i] = rand() % 100 ;
    }
/*
    int array[10] = {0x10 ,0x37  ,0x4f  ,0x39  ,0x3e  ,0x39 , 0x13  ,0x2b ,0x4f,0x8};
    int len = sizeof array / sizeof (int);
*/

    printf("start->\n");
    for (int i =0 ; i < len ; i++){
    ¦   ¦printf("%d,",array[i]);
    }

  info(array,0, len-1);
    printf("\nend->\n");
    int tmp = 0;
    for (int i =0 ; i < len ; i++){
        if(array[i] >= tmp)
            tmp = array[i];
        else{
            printf("排序失败"); break;
        }

        printf("%d,",tmp);
        if(len-1 == i)
            printf("\n完成排序\n");
    }
    return 0;
}

运行结果

start->
34,37,27,10,66,87,11,46,66,45,
end->
10,11,27,34,37,45,46,66,66,87,
完成排序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值