插入排序
插入排序是一种简单直观的排序算法,其基本思想是将一个元素逐步插入已排好序的部分,从而使整个序列逐步有序。
以下是插入排序的基本思路:
1. **初始状态:** 将数组分为已排序部分和未排序部分。初始时已排序部分只包含第一个元素,未排序部分包含其余元素。
2. **遍历未排序部分:** 从第二个元素开始,逐个遍历未排序部分的元素。
3. **插入操作:** 对于每个未排序部分的元素,将其与已排序部分的元素进行比较。如果已排序部分的元素比当前未排序元素大,就将已排序部分的元素后移一个位置,为当前元素腾出插入的位置。
4. **插入位置:** 重复比较和后移操作,直到找到已排序部分中比当前未排序元素小的位置,然后将当前未排序元素插入该位置。
5. **继续遍历:** 继续遍历未排序部分的下一个元素,重复步骤 3 和 4。
6. **重复步骤:** 重复执行上述步骤,直到所有未排序部分的元素都被插入到已排序部分中。
7. **排序完成:** 当所有未排序元素都被插入到已排序部分后,整个数组变为有序。
插入排序是一个稳定的排序算法,适用于小型数组和基本有序的数组。然而,对于大型数据集来说,插入排序的性能可能会比较差,因为每次插入都需要进行多次比较和移动操作。
总之,插入排序的主要思想是逐个将未排序部分的元素插入到已排序部分的适当位置,以获得有序数组。
void InsertSort(int* arr, int len) {
int i, j;
for (i = 1; i < len; i++) {
int key = arr[i];
int j = i - 1;
for (j; key < arr[j]&&j>=0; j--) {
arr[j + 1] = arr[j];
}
arr[j + 1] = key;
}
}
希尔排序
希尔排序(Shell Sort)是插入排序的一种变体,它通过将数组分为多个子序列来实现部分排序,然后逐渐减小子序列的长度,最终完成整个数组的排序。希尔排序的核心思想是通过跳跃式的插入排序来使数组更快地接近有序状态,从而减少后续的比较和移动操作。
以下是希尔排序的基本思想和步骤:
-
选择一个增量序列: 增量序列是一个递减的正整数序列,它决定了子序列的间隔。常用的增量序列有希尔序列、Hibbard序列等。
-
分组和排序: 根据选定的增量序列,将数组分成多个子序列,并对每个子序列进行插入排序。
-
逐步缩小增量: 重复步骤 2,逐步缩小增量,直到增量为1。当增量为1时,整个数组将变为一个大的子序列,进行最后一次插入排序即可。
希尔排序的关键在于选择合适的增量序列,不同的增量序列会影响排序的性能。希尔排序的时间复杂度取决于增量序列的选择,最坏情况下可以达到 O(n^2),但通常情况下具有较好的性能。
void ShellSort(int* arr, int len) {
int i, j, key;
int gap = len / 2;
for (gap; gap > 0; gap = gap / 2) {
for (int i = gap; i < len; i++) {
key = arr[i];
for (j = i; arr[j-gap] > key&&j>=gap; j -= gap) {
arr[j] = arr[j-gap];
}
arr[j] = key;
}
}
}