60
72
83
73
88
85
可以看出a[5]前面的数字都小于它 , a[5]后面的数字都大于它 。因此再对a[0…4]和a[6…9]这二个子区间重复上述步骤就可以了 。
对挖坑填数进行总结
1.i =L; j = R; 将基准数挖出形成第一个坑a[i] 。
2.j--由后向前找比它小的数 , 找到后挖出此数填前一个坑a[i]中 。
3.i++由前向后找比它大的数 , 找到后也挖出此数填到前一个坑a[j]中 。
4.再重复执行2 , 3二步 , 直到i==j , 将基准数填入a[i]中 。
照着这个总结很容易实现挖坑填数的代码:
[cpp] view plaincopy
- int AdjustArray(int s[], int l, int r) //返回调整后基准数的位置
- {
- int i = l, j = r;
- int x = s[l]; //s[l]即s[i]就是第一个坑
- while (i < j)
- {
- // 从右向左找小于x的数来填s[i]
- while(i < j && s[j] >= x)
- j--;
- if(i < j)
- {
- s[i] = s[j]; //将s[j]填到s[i]中 , s[j]就形成了一个新的坑
- i++;
- }
- // 从左向右找大于或等于x的数来填s[j]
- while(i < j && s[i] < x)
- i++;
- if(i < j)
- {
- s[j] = s[i]; //将s[i]填到s[j]中 , s[i]就形成了一个新的坑
- j--;
- }
- }
- //退出时 , i等于j 。将x填到这个坑中 。
- s[i] = x;
- return i;
- }
再写分治法的代码:
[cpp] view plaincopy
- void quick_sort1(int s[], int l, int r)
- {
- if (l < r)
- {
- int i = AdjustArray(s, l, r);//先成挖坑填数法调整s[]
- quick_sort1(s, l, i - 1); // 递归调用
- quick_sort1(s, i + 1, r);
- }
- }
这样的代码显然不够简洁 , 对其组合整理下:
[cpp] view plaincopy
- //快速排序
- void quick_sort(int s[], int l, int r)
- {
- if (l < r)
- {
- //Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1
- int i = l, j = r, x = s[l];
- while (i < j)
- {
- while(i < j && s[j] >= x) // 从右向左找第一个小于x的数
- j--;
- if(i < j)
- s[i++] = s[j];
- while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数
- i++;
- if(i < j)
- s[j--] = s[i];
- }
- s[i] = x;
- quick_sort(s, l, i - 1); // 递归调用
- quick_sort(s, i + 1, r);
- }
- }
快速排序还有很多改进版本 , 如随机选择基准数 , 区间内数据较少时直接用另的方法排序以减小递归深度 。有兴趣的筒子可以再深入的研究下 。
注1 , 有的书上是以中间的数作为基准数的 , 要实现这个方便非常方便 , 直接将中间的数和第一个数进行交换就可以了 。
- OPPO手机关闭这个开关,不仅省电省流量,还让手机不再卡顿更流畅
- 实测:荣耀30和荣耀30s跑分曝光,画面质感流畅,跑分不相上下
- 2020年,四川省的高考状元都选择了北京大学,北京大学真厉害
- 吉林省一级建造师的报考条件是什么
- 拼多多省钱月卡怎么关闭自动续费?
- 湖北省征地技术方案和规定程序调整补偿标准是怎样的
- 甘肃省政府服务网统一公共支付平台如何打印票据
- MIUI12还有什么缺点吗?
- WiFi6终极测试,局域网共享2G大小电影20秒复制完成,速率达千兆
- 支付宝如何查核酸检测报告