c语言实现数组显示与排序,C语言实现数组快速排序

/*

说明:

代码参考过网上代码,但分析为个人原创,本贴重在说明快速排序算法的思想和运行过程。

*/

代码部分:

#include

#include

void quickSort(int* arr,int startPos, int endPos)

{

int i, j;

int key;

key = arr[startPos];

i = startPos;

j = endPos;

while (i

{

while (arr[j] >= key && i

arr[i] = arr[j];

while (arr[i] <= key && ikey或遍历完

arr[j] = arr[i];

}

arr[i] = key;

if (i - 1>startPos) quickSort(arr, startPos, i - 1); //————1 如果key前还有两个及以上的数,排key前的数(有一个的话自然就不用排了)

if (endPos>i + 1) quickSort(arr, i + 1, endPos);//————2 如果key后还有两个及以上的数,排key后的数

}

int main()

{

int a[11], i;

for (i = 0; i<11; i++)

scanf_s("%d", &a[i]);

quickSort(a, 0, 10);

for (i = 0; i<11; i++)

printf("%d ", a[i]);

printf("\n");

return 0;

}

解析部分:

/*

以数组 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10]

0 2 32 39 23 45 36 57 14 27 39 为例,说明核心代码的实现机制

第一轮:

首先进入quickSort(a, 0, 10); key=0,i=0,j=10,进入外层while,进入第一个内层while,由于0是数组中最小的,故j一直扫到头,j=0,arr[0] = arr[0]=0;

显然无法进入第二个内层while,由于i=j=0,结束外层while,执行a[0]=key=0;显然不进入第一个if,进入第二个if,执行quickSort(a, 1, 10);进行从a[1]到

a[10]的排序,第一轮结束。

第二轮;

执行quickSort(a, 1, 10),key=2,i=1,j=10,进入外层while,进入第一个内层while,由于2是传入段中最小的,故j一直扫到头,j=1,arr[1] = arr[1]=2;显然

无法进入第二个内层while,由于i=j=1,结束外层while,执行a[1]=key=2;显然不进入第一个if,进入第二个if,执行quickSort(a, 2, 10);进行从a[2]到

a[10]的排序,第二轮结束。

第三轮:

执行quickSort(a, 2, 10),key=32,i=2,j=10,进入外层while,进入第一个内层while,a[10]=39>key=32,--j,j变为9;a[9]=27

执行a[i]=a[2]=a[j]=a[9]=27,数组变为

a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10]

0 2 27 39 23 45 36 57 14 27 39

注意此时a[j](即a[9])的值存入a[i](即a[2])中,a[j]可以被再赋值,32呢?32怎么没了呢?注意32始终由key保存,不用担心。注意此时i=2,j=9;

程序顺次执行,满足第二个内层while,进入,开始从左往右扫。a[2]=27

的,而送给的条件是a[j](即这里的a[i])key=32,执行a[j](前边已经说过,此时a[j]=a[9]的值已保存到a[2]中,a[j]可修改)=a[9]=a[3]

=39,数组变为

a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10]

0 2 27 39 23 45 36 57 14 39 39

注意此时a[i]=a[3]又变为可修改。

注意此时i=3

继续执行第一个内层while,a[j]=a[9]=39>key=32,--j,j变为8(这也是必然的,道理同前边分析);a[j]=a[8]=14

执行a[i]=a[3]=a[j]=a[8]=14,数组变为

a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10]

0 2 27 14 23 45 36 57 14 39 39

注意此时a[j]=a[8]又变为可修改。此时i=3,j=8;

程序顺次执行,满足第二个内层while,进入,开始从左往右扫。a[i]=a[3]=14

45>key=32,退出第二个内层while,执行a[j]=a[8]=a[i]=a[5]=45,数组变为

a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10]

0 2 27 14 23 45 36 57 45 39 39

注意此时a[i]=a[5]可修改,且i=5,j=8,未跳出外层while。

继续执行第一个内层while,a[j]=a[8]=45>key=32,--j,j变为7(必然);a[j]=a[7]=57>key=32,--j,j变为6;a[j]=a[6]=36>key=32,--j,j变为5注意到此时i=j=5,

直接退出三个while。执行a[i]=a[5]=key=32,数组变为

a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10]

0 2 27 14 23 32 36 57 45 39 39

注意此时a[5]前的数都小于key=32,a[5]后的数都大于key=32,且startPos=2,endPos=10。

显然两个if都满足,(这是人一次性判断的,计算机只能先判断第一个if,等程序再返回到本轮时再判断第二个if,我们一次性判断是为了说明方便)首先进入第一个

if,执行quickSort(a, 2, 4),排a[5]前面的a[2]到a[4](a[0],a[1]在第二轮后已排好),进入下一轮(第四轮),但第三轮未结束,因为计算机还并未判断第二个

if。

第四轮:

执行quickSort(a, 2, 4),key=a[2]=27,i=2,j=4,startPos=2,endPos=4。

进入外层while,进入第一个内层while,a[j]=a[4]=23

a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10]

0 2 23 14 23 32 36 57 45 39 39

此时a[j]=a[4]可修改,且i=2,j=4,程序顺次执行,进入第二个while,a[i]=a[2]=23

j=4,退出所有循环,执行a[i]=a[4]=key=27,数组变为

a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10]

0 2 23 14 27 32 36 57 45 39 39

此时i=j=4,startPos=2,endPos=4,显然满足第一个if不满足第二个if(key后已无数),故执行quickSort(a, 2, 3)(排a[4]前的),进入下一轮(第五轮),但

第四轮未结束,因为计算机还并未判断第二个if。

第五轮:

执行quickSort(a, 2,3),key=a[2]=23,i=2,j=3,startPos=2,endPos=3。

进入外层while,进入第一个内层while,a[j]=a[3]=14

a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10]

0 2 14 14 23 32 36 57 45 39 39

此时a[j]=a[3]可修改,且i=2,j=3,程序顺次执行,进入第二个while,a[i]=a[2]=14

key=23,数组变为

a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10]

0 2 14 23 27 32 36 57 45 39 39

此时i=j=3,startPos=2,endPos=3,显然不满足第一个if,再判断第二个,也不满足,故第五轮结束,返回到上一轮(第四轮)的第二个if处,前面已经分析过,不

满足第二if,故第四轮结束,返回到上一轮(第三轮)的第二个if处(至此,到第三轮最终的a[i]=a[5]=key=32前的元素,都已排好),这次满足。执行

quickSort(a, 6, 10),排a[5]后的元素,进入下一轮(记为第四*轮,为的是与上面的第四轮区别,同时也为了体现两者的联系)。第三轮结束。

第四*轮:

执行quickSort(a, 6, 10),key=a[6]=36,i=6,j=10,startPos=6,endPos=10。

此时a[j]=a[3]可修改,且i=2,j=3,程序顺次执行,进入第二个while,a[i]=a[2]=14

a[j]=a[10]=39>key=36,--j,j变为9;a[j]=a[9]=39>key=36,--j,j变为8;a[j]=a[8]=45>key=36,--j,j变为7;a[j]=a[7]=57>key=36,--j,j变为6;注意到i=j=6,

退出所有while,执行a[i]=a[6]=key=36,数组不变。此时i=j=6,startPos=6,endPos=10。显然不满足第一个if,满足第二个if,执行quickSort(a, 7, 10)(排

a[6]后的元素),进入第五*轮,第四*轮结束。

第五*轮:

执行quickSort(a, 7, 10),key=a[7]=57,i=7,j=10,startPos=7,endPos=10。

a[j]=a[10]=39

a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10]

0 2 14 23 27 32 36 39 45 39 39

此时i=7,j=10,程序顺次执行,进入第二个内层while,a[i]=a[7]=39

i变为10;注意到i=j=10,退出所有while,执行a[i]=a[10]=key=57。数组变为

a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10]

0 2 14 23 27 32 36 39 45 39 57

此时i=j=10,startPos=7,endPos=10。显然满足第一个if,不满足第二个if(a[i]=a[10]后面已没有元素),执行quickSort(a, 7, 9)(排a[10]前面的元素),进入

第六*轮,但未退出第五*轮,因为计算机并还未判断第二个if。

第六*轮:

执行quickSort(a, 7, 9),key=a[7]=39,i=7,j=9,startPos=7,endPos=9。

a[j]=a[9]=39=key=39,--j,j变为8;a[j]=a[8]=4>key=39,--j,j变为7;注意到i=j=7,退出所有while,执行a[i]=a[7]=key=39,数组不变。此时i=j=7,startPos=7,

endPos=9。显然不满足第一个if(a[i]=a[7]前已无元素),满足第二个,执行quickSort(a, 8, 9)(排a[7]后面的元素),,进入第七*轮,第六*轮结束。

第七*轮:

执行quickSort(a, 8, 9),key=a[8]=45,i=8,j=9,startPos=8,endPos=9。

a[j]=a[9]=39

a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10]

0 2 14 23 27 32 36 39 39 39 39

此时i=8,j=9,程序顺次执行,进入第二个内层while,a[i]=a[8]=39

注意到i=j=9,退出所有while,执行a[i]=a[10]=key=57。数组变为

a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10]

0 2 14 23 27 32 36 39 39 45 57

此时i=j=9,startPos=8,endPos=9,显然不满足第一个if,再判断第二个,也不满足,第七*轮结束。程序回到第五*轮的第二个if,前面已经分析过,不满足,故第五*轮结束。

至此,整个quickSort函数结束,数组已排好,如上所示。

*/

如果大家觉得分析太多,不想看,建议大家按照代码手动执行一下,就豁然开朗了。当然,过程中可以结合、参考在下的分析。文章来源:

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值