持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情
2022计算机考研408—数据结构—排序 手把手教学考研大纲范围内的排序 22考研大纲数据结构要求的是C/C++,笔者以前使用的都是Java,对于C++还很欠缺, 如有什么建议或者不足欢迎大佬评论区或者私信指出
Talk is cheap. Show me the code. 理论到处都有,代码加例题自己练习才能真的学会
希尔排序
思路:
希尔排序其实可以看做是插入排序的变种
插入排序是循环到某个元素就像前找合适的位置,把当前元素到合适位置的值都要向后移动一遍
插入排序对于有序的数组,比较和移动的次数都比较少
希尔排序就是把插入排序进行分组化
分组是按照长度每次除2分的,这样最后一次肯定是一个组一个元素,就相当于最原始的插入排序了 而他前面做的按组排序就是为了让这个数组变成一个有大概顺序的数组,使后面的插入排序能减少比较和移动的次数
按下图为例子,数组长度15 第一次按照7个增量分组,第二次按照3个增量,第三次按照1个增量分组
第一次循环的增量为7
第一次是下标 0 与 0+7比较 1与1+7比较 …… 7 与 7+7比较
第一次循环完,这些位置上有了个大概的顺序
第二次循环的增量为3
第二次是下标 0与3与6与9与12比较 1与4与7与10与13 2与5与8与11与14
第二次循环完,这些位置上有了大概的顺序
第三次循环的增量为1
就相当于简单的插入排序
希尔排序的精髓就在于,对于一个大概有序的数组,插入排序的比较和移动次数都比较少
PS:小编作图能力有限,上图是当来的
//除main方法外的其他cout输出都是为了让读者更清楚的了解每次循环后进行排序的下标
#include <iostream>
#include <vector>
using namespace std;
void shellSort(vector<int> &num);
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);
}
shellSort(num); //调用自定义的排序方法
cout << "\n\n排序后" << "\n";
for (int i = 0; i < num.size(); i++) {
cout << num[i] << " "; //输出
}
return 0;
}
void shellSort(vector<int> &num) {
int len = num.size();
for (int d = len / 2; d > 0; d/=2) { //按照增量分组,增量每次/2
cout << "\n\n增量为" << d;
for (int i = d; i < len; i++) { //类似插入排序,每次都比较i之前的,
cout << "\n此次排序的下标为:" << i;
for (int j = i - d; j >=0; j-=d) {
cout << " " << j;
//这里i-d其实也就是从前面开始,
// j每次都是j-=d,因为我们是按照相同增量分为一组的
// 对比上图更容易理解
if (num[j] > num[j + d]) { //只要前面的比后面的大,就交换位置
int temp = num[j];
num[j] = num[j + d];
num[j + d] = temp;
}
}
//每次循环都把数组的变动输出出来
cout << "\n";
for (int j = 0; j < num.size(); j++) {
cout << num[j] << " ";
}
}
}
}