2022计算机考研408—数据结构—排序 手把手教学考研大纲范围内的排序 22考研大纲数据结构要求的是C/C++,笔者以前使用的都是Java,对于C++还很欠缺, 如有什么建议或者不足欢迎大佬评论区或者私信指出
Talk is cheap. Show me the code. 理论到处都有,代码加例题自己练习才能真的学会
快速排序
思路: 从未排序的数组中,一个一个的寻找,寻找当前值应该在排序后数组的位置, 以此类推,把每个值的位置都确定了以后,此数组就变成了排序后的数组 也是分段进行确定某个值最终排序后的下标
先选取第一个值,用一个临时变量保存这个值,然后双指针i表示这段范围的开头,j这段范围的结尾
j负责从后向前找小于临时变量的值,找到以后就把j的值放到i那,
此时j位置就空出来了,我们当作把临时变量的值放到j这里
i负责从前向后找大于临时变量的值,找到后就放到j那里,
此时i位置就空出来了,我们同样当作把临时变量的值放到i这里
不断循环这两步的操作,
i是从前向后,j是从后向前
循环结束的条件就是i==j 也就是临时变量排序后数组的位置,
按照这种排序方式,结束后,
比临时变量小的都在临时变量左边(左边不一定是排好序的),
比临时变量大的都在临时变量右边(右边不一定是排好序的),
也就是说临时变量当前的下标就是排序后的下标
当前临时变量的位置确定好以后,我们可以分为前半部分和后半部分继续这种操作
以此类推,当每个值最终排序后的位置都确定的时候,此数组为排序后的数组
复制代码
下图为确定好一个值的最终位置的排序图
临时变量为50,左指针low,右指针high
右指针找到20比临时变量小,交换两个值
左指针找到90比临时变量大,交换两个值
右指针找到40比临时变量小,交换两个值位置
左指针找到70比临时变量小,交换两个值的位置
右指针左移与左指针重合,当前位置为50排序后的最终位置
我们发现,左边的数都比50小,右边的数都比50大,
当前数的位置就是排序后当前数的位置 然后在把左边的数组按照这种方法,右边的数组按照这种方法
以此类推每个值的最终下标都确定下来了,数组为排序后的数组
PS:图仍然是某度当来的o( ̄▽ ̄)ブ
using namespace std;
void quickSort(vector<int> &num, int left, int right);
int main() {
int n; //n为将要输入的数组长度
cin >> n; //输入n cin方法需要上面使用std
vector<int> num; //定义vector 记得上面导入vector
int temp; //temp为输入vector时的中间变量
for (int i = 0; i < n; i++) {
cin >> temp; //输入
num.push_back(temp);
}
quickSort(num, 0, num.size() - 1); //调用自定义的排序方法
cout << "\n\n排序后" << "\n";
for (int i = 0; i < num.size(); i++) {
cout << num[i] << " "; //输出
}
return 0;
}
void quickSort(vector<int> &num, int left, int right) {
if (left >= right) return; //如果左节点>=右节点了,证明排序结束了,返回即可
int temp = num[left]; //保存一下当前左节点的值,此次排序就是确定当前左节点的值
int l = left; //保存一下原始的左右边界
int r = right;
while (left < right) { //循环的结束条件就是左指针 == 右指针,相等时就为temp排序后的最终位置
while (left < right && temp < num[right]) { //右指针找比temp小的值,如果没找到就一直找
right--;
}
if (left < right) { //上面循环结束了就证明找到了,如果left == right,那么最终位置就确定好了,
num[left] = num[right]; //然后把比temp小的放到左面left位置那里,然后left指向下一个值
left++; //可能这里有些疑问,上面描述的是交换,这里没有交换,实际上每次都交换,换来换去,每次都重复换temp这个数
} //不如直接赋值,然后把这个重复数直接放到最后确定的位置
while (left < right && num[left] < temp) { //这里是左指针找比temp大的数,找到就退出循环了,
left++;
}
if (left < right) { //与上面相反的道理,把比temp大的数放到right,right指针左移
num[right] = num[left];
right--;
}
}
num[left] = temp; //循环结束就是确定了temp最终的位置,左指针==右指针
//每次循环都把数组的变动输出出来
cout << "\n左边界下标:" << l << " 右边界下标:" << r << " 当前循环确定的下标为:" << left << "\n";
for (int j = 0; j < num.size(); j++) {
cout << num[j] << " ";
}
quickSort(num, l, left - 1); //temp确定好了位置,把temp左面的数组和右面的数组分别进行这种方法排序
quickSort(num, left + 1, r); //当每个值的下标都确定的时候,该数组以完成排序
}
复制代码
作者:发呆哥
链接:https://juejin.cn/post/7104791990113419272
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。