目录
前言
排序是重要又较为简单的算法之一,个人认为学习算法建议先学习排序,排序有十种重要的排序方法,有些好,有些坏。
十大排序算法包括哪些
十大排序算法包括冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序、桶排序、基数排序。
今天我来讲讲希尔排序。
希尔排序原理
希尔排序的基本思想是将待排序的元素分为多个子序列,每个子序列通过插入排序进行排序。这些子序列是由原始序列中相隔一定增量的元素组成的。初始时,增量较大,元素被分成多个组进行插入排序;随着增量的逐渐减小,分组越来越细,最终当增量减小到1时,整个数组作为一个组进行最后一次插入排序,完成排序。
希尔排序基本信息
英文名 | shell sort |
时间复杂度 | 小于O(n^2) |
空间复杂度 | O(1) |
是否稳定 | 否 |
代码实现
代码思路
- 选择增量:初始时,选择一个较大的增量(如数组长度的一半或三分之一),将数组分成多个子序列。
- 分组排序:对每个子序列进行插入排序。例如,第一个元素不动,第二个元素与第一个元素比较,如果大于则交换位置,然后第三个元素与前两个元素比较,以此类推。
- 减小增量:逐渐减小增量(例如每次减小为原来的三分之一),重复上述分组和排序过程。
- 最终排序:当增量减小到1时,对整个数组进行一次插入排序,完成排序。
代码实现
/*头文件部分*/
#include <iostream>
using namespace std;
/*希尔排序部分*/
void shellSort(int arr[], int n) {
for (int gap = n / 2; gap > 0; gap /= 2) {
for (int i = gap; i < n; i ++) {
int temp = arr[i];
int j;
for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {
arr[j] = arr[j - gap];
}
arr[j] = temp;
}
}
}
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++)
cout << "第" << i + 1 << "个数:" << arr[i] << endl;
}
/*主函数部分*/
int main() {
int a[10000], n;
cin >> n;
for (int i = 0; i < n; i++)
cin >> a[i];
shellSort(a, n);
printArray(a, n);
return 0;
}
实例
【模板】排序
题目描述
将读入的 N 个数从小到大排序后输出。
输入格式
第一行为一个正整数 N。
第二行包含 N 个空格隔开的正整数 ai,为你需要进行排序的数。
输出格式
将给定的 N 个数从小到大输出,数之间空格隔开,行末换行且无空格。
样例1
样例输入1
5
4 2 4 5 1
样例输出1
1 2 4 4 5
本题来自洛谷题目
P1177 【模板】排序https://www.luogu.com.cn/problem/P1177
代码
#include <iostream>
using namespace std;
void shellSort(int arr[], int n) {
for (int gap = n / 2; gap > 0; gap /= 2) {
for (int i = gap; i < n; i ++) {
int temp = arr[i];
int j;
for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {
arr[j] = arr[j - gap];
}
arr[j] = temp;
}
}
}
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
}
int main() {
int a[10000], n;
cin >> n;
for (int i = 0; i < n; i++)
cin >> a[i];
shellSort(a, n);
printArray(a, n);
return 0;
}
总结
希尔排序(Shell Sort)是一种基于插入排序的算法,由Donald Shell于1959年提出。它通过将待排序的元素分成多个子序列,对每个子序列进行插入排序,然后逐渐减小子序列的间隔,最终达到整个序列的有序排列。希尔排序的核心思想是利用插入排序在已排序序列上高效工作的特性,通过减少数据移动来提高排序效率12。
希尔排序的基本步骤
- 分组:将待排序的元素分成多个子序列,每个子序列包含相隔一定增量的元素。
- 插入排序:对每个子序列进行插入排序。
- 减小增量:逐渐减小分组间隔,重复上述过程,直到增量为1,对整个序列进行一次插入排序。
希尔排序的优缺点
优点:
- 效率较高:在数据量较大且初始状态较为有序时,希尔排序的效率明显高于传统的插入排序。
- 减少移动:通过分组排序,减少了元素的移动次数,从而提高了排序效率。
缺点:
- 不稳定:希尔排序不是稳定的排序算法,相同的元素在排序过程中可能会改变相对位置。
- 最坏情况效率低:在最坏的情况下,希尔排序的时间复杂度可以达到O(n^2)。
希尔排序的应用场景
- 大数据集:当数据集较大且初始状态较为有序时,希尔排序可以显著提高排序效率。
- 内存限制:由于希尔排序不需要额外的存储空间,适合内存有限的环境。
你学废了吗?
下期预告:十大排序算法之插入排序。