排序算法--快速排序

我觉得其实对于排序,讲很多的字面上的道理我觉得枯燥,所以对于快速排序,我还是借用别人的图片来说一下。假如现在我们需要用快速排序来对数据6  1  2 7  9  3  4  5 10  8进行排序,我们怎么办呢?

    首先在这个序列中随便找一个数作为基准数。为了方便,就让第一个数6作为基准数吧。接下来,需要将这个序列中所有比基准数大的数放在6的右边,比基准数小的数放在6的左边,在初始状态下,数字6在序列的第1位。我们的目标是将6挪到序列中间的某个位置,假设这个位置是k。现在就需要寻找这个k,并且以第k位为分界点,左边的数都小于等于6,右边的数都大于等于6


    现在:分别从初始序列“6  1  2  7  9  3  4  5 10  8”两端开始“探测”。先从找一个小于6的数,再从找一个大于6的数,然后交换他们。这里可以用两个变量i和j,分别指向序列最左边和最右边。我们为这两个变量起个好听的名字“哨兵i”和“哨兵j”。刚开始的时候让哨兵i指向序列的最左边(即i=1),指向数字6。让哨兵j指向序列的最右边(即=10),指向数字



首先哨兵j开始出动。因为此处设置的基准数是最左边的数,所以需要让哨兵j先出动,这一点非常重要(请自己想一想为什么)。哨兵j一步一步地向左挪动(即j--),直到找到一个小于6的数停下来。接下来哨兵i再一步一步向右挪动(即i++),直到找到一个数大于6的数停下来。最后哨兵j停在了数字5面前,哨兵i停在了数字7面前,然后交换数据


继续之前的操作


直到相遇


到此第一轮“探测”真正结束。此时以基准数6为分界点,6左边的数都小于等于6,6右边的数都大于等于6。回顾一下刚才的过程,其实哨兵j的使命就是要找小于基准数的数,而哨兵i的使命就是要找大于基准数的数,直到i和j碰头为止。

基准点K找到之后我们就可以用分治的思想递归之后的过程,就是6左边的数据执行前面的操作,右边的数据同样如此,在执行的过程中里面继续递归这个过程,直到结束,组合在一起,就是排列好的数据。

#include <stdio.h> 
int a[101],n;//定义全局变量,这两个变量需要在子函数中使用 
void quicksort(int left,int right) 

int i,j,t,temp; 
if(left>right) 
return; 
temp=a[left]; //temp中存的就是基准数 
i=left; 
j=right; 
while(i!=j) 

while(a[j]>=temp && i<j) //顺序很重要,要先从右边开始找 
j--; 
while(a[i]<=temp && i<j) //再找右边的 
i++; 
//交换两个数在数组中的位置 
if(i<j) 

t=a[i]; 
a[i]=a[j]; 
a[j]=t; 


//最终将基准数归位 。在这里注意是i 不是j 至于为什么大家想一下
a[left]=a[i]; 
a[i]=temp; 
quicksort(left,i-1);//继续处理左边的,这里是一个递归的过程 
quicksort(i+1,right);//继续处理右边的 ,这里是一个递归的过程 

int main() 

int i;
//读入数据 
scanf("%d",&n); 
for(i=1;i<=n;i++) 
scanf("%d",&a[i]); 
quicksort(1,n); //快速排序调用 
//输出排序后的结果 
for(i=1;i<=n;i++) 
printf("%d ",a[i]); 
return 0; 
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值