📜  数据结构和算法插入排序(1)

📅  最后修改于: 2023-12-03 15:40:01.715000             🧑  作者: Mango

数据结构和算法:插入排序

插入排序是一种常见的简单排序算法,其基本思想是将一个记录插入到已经有序的记录序列中,从而得到一个新的有序序列。插入排序的具体实现可以采用直接插入排序、二分插入排序和希尔排序三种不同的方法。

直接插入排序

直接插入排序是将一个记录插入到已经有序的记录序列中的方法,具体实现如下:

void insertSort(int arr[], int n) {
    int i, j;
    for (i = 1; i < n; i++) {
        int temp = arr[i];
        for (j = i-1; j >= 0 && arr[j] > temp; j--) {
            arr[j+1] = arr[j];
        }
        arr[j+1] = temp;
    }
}

其中,arr 为待排序数组,n 表示待排序元素个数,temp 为当前待插入元素,i 为循环变量,j 为查找插入位置时的循环变量。具体实现过程如下:

  1. 第一次插入时,数组中只有一个元素,因此已经是有序的,不需要进行插入操作;
  2. 第二次插入时,将有序序列扩展到前两个元素,将第二个元素插入到第一个元素中,此时数组较小的元素已经有序;
  3. 第三次插入时,将有序序列扩展到前三个元素,将第三个元素插入到前两个元素中,此时数组中前三个元素已经有序;
  4. 以此类推,依次将后面的元素插入到有序序列中,直到全部数据元素插入完毕。
二分插入排序

二分插入排序是对直接插入排序的改进,其查找插入位置时采用二分查找法,具体实现如下:

void insertSort2(int arr[], int n) {
    int i, j;
    for (i = 1; i < n; i++) {
        int temp = arr[i];
        int low = 0, high = i-1;
        while (low <= high) {
            int mid = (low + high) / 2;
            if (arr[mid] > temp)
                high = mid - 1;
            else
                low = mid + 1;
        }
        for (j = i-1; j >= high+1; j--) {
            arr[j+1] = arr[j];
        }
        arr[high+1] = temp;
    }
}

其中,变量 lowhigh 分别表示查找范围的下界和上界,mid 表示查找范围的中间值,其他变量与直接插入排序中一致。具体实现过程如下:

  1. 第一次插入时,数组中只有一个元素,因此已经是有序的,不需要进行插入操作;
  2. 第二次插入时,将有序序列扩展到前两个元素,将第二个元素插入到第一个元素中,此时数组较小的元素已经有序;
  3. 第三次插入时,将有序序列扩展到前三个元素,将第三个元素插入到前两个元素中,此时数组中前三个元素已经有序;
  4. 以此类推,依次将后面的元素插入到有序序列中,查找插入位置时采用二分查找法,直到全部数据元素插入完毕。
希尔排序

希尔排序是对插入排序的改进,其按照一定的步长分组,对每个分组进行插入排序,然后再缩小步长,对每个分组进行插入排序,直到步长为1,进行最后一次插入排序,具体实现如下:

void shellSort(int arr[], int n) {
    int i, j, gap;
    for (gap = n/2; gap > 0; gap /= 2) {
        for (i = 0; i < gap; i++) {
            for (j = i+gap; j < n; j += gap) {
                int temp = arr[j];
                int k = j - gap;
                while (k >= 0 && arr[k] > temp) {
                    arr[k+gap] = arr[k];
                    k -= gap;
                }
                arr[k+gap] = temp;
            }
        }
    }
}

其中,gap 表示步长大小,i 表示分组的起始下标,j 表示分组的结束下标,k 表示待插入元素的位置,其他变量与直接插入排序中一致。具体实现过程如下:

  1. 第一次插入时,将所有元素按照步长分为若干个子序列,对每个子序列进行直接插入排序;
  2. 第二次插入时,将步长缩小为原来的一半,将每个子序列中的元素再次按照步长分为若干个子序列,对每个子序列进行直接插入排序;
  3. 以此类推,直到步长为1,进行最后一次直接插入排序。
总结

插入排序是一种简单有效的排序算法,其具有稳定性和适应性等优势,在实际应用中表现良好。无论是直接插入排序、二分插入排序还是希尔排序,都是基于插入排序的基本思想,其具体实现不同,可以根据实际应用场景选择不同的算法进行优化。