天天看點

從小到大輕松排序:C語言插入排序知識點深入解析

作者:嵌入式講堂

目錄

  1. 前言
  2. 什麼是插入排序
  3. 插入排序的基本思想
  4. 插入排序的實作
  5. 插入排序的優化
  6. 插入排序的應用
  7. 總結

前言

在我們的日常生活中,排序是一個非常常見的操作。比如,我們需要将一堆書按照作者的名字排序,或者将一堆數字按照大小排序。在計算機科學中,排序也是一個非常重要的算法。插入排序是其中一種非常基礎的排序算法,本文将深入解析插入排序的知識點。

什麼是插入排序

插入排序是一種簡單直覺的排序算法,它的基本思想是将一個待排序的序列分成兩部分,一部分是已經排好序的,另一部分是未排序的。然後,将未排序的部分中的每一個元素插入到已排序的部分中的合适位置,直到所有元素都被插入到已排序的部分中。

插入排序的時間複雜度為O(n^2),空間複雜度為O(1),是一種穩定的排序算法。

插入排序的基本思想

插入排序的基本思想是将一個待排序的序列分成兩部分,一部分是已經排好序的,另一部分是未排序的。然後,将未排序的部分中的每一個元素插入到已排序的部分中的合适位置,直到所有元素都被插入到已排序的部分中。

下面是一個簡單的例子,假設我們要将數組 [5, 2, 4, 6, 1, 3] 從小到大排序。我們可以将它分成兩部分,一部分是已經排好序的 [5],另一部分是未排序的 [2, 4, 6, 1, 3]。然後,我們将未排序的部分中的第一個元素 2 插入到已排序的部分中的合适位置,得到 [2, 5]。接着,我們将未排序的部分中的第二個元素 4 插入到已排序的部分中的合适位置,得到 [2, 4, 5]。以此類推,最終得到排好序的數組 [1, 2, 3, 4, 5, 6]。

插入排序的實作

插入排序的實作非常簡單,我們可以使用兩個循環來實作。第一個循環用來周遊未排序的部分,第二個循環用來周遊已排序的部分,找到合适的位置插入元素。

下面是一個簡單的 C 語言實作:

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

在這個實作中,我們使用了兩個循環。第一個循環用來周遊未排序的部分,第二個循環用來周遊已排序的部分,找到合适的位置插入元素。在第二個循環中,我們使用了一個 while 循環來找到合适的位置。

插入排序的優化

雖然插入排序非常簡單,但是它的時間複雜度為O(n^2)

,在處理大規模資料時效率較低。是以,我們需要對插入排序進行優化。

1. 二分查找優化

在插入排序中,我們需要在已排序的部分中找到合适的位置插入元素。如果我們使用二分查找來查找合适的位置,可以将時間複雜度降低到O(n \log n)。

下面是一個使用二分查找優化的 C 語言實作:

void insertion_sort(int arr[], int n) {
    int i, j, key, left, right, mid;
    for (i = 1; i < n; i++) {
        key = arr[i];
        left = 0;
        right = i - 1;
        while (left <= right) {
            mid = (left + right) / 2;
            if (arr[mid] > key) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        for (j = i - 1; j >= left; j--) {
            arr[j + 1] = arr[j];
        }
        arr[left] = key;
    }
}           

在這個實作中,我們使用了二分查找來查找合适的位置。在第一個循環中,我們使用了一個 while 循環來查找合适的位置。在第二個循環中,我們使用了一個 for 循環來将已排序的部分中的元素向右移動。

2. 希爾排序優化

希爾排序是一種基于插入排序的排序算法,它通過将待排序的序列分成若幹個子序列來提高插入排序的效率。希爾排序的時間複雜度為O(n \log n)

,是一種比較高效的排序算法。

下面是一個使用希爾排序優化的 C 語言實作:

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

在這個實作中,我們使用了希爾排序來優化插入排序。在第一個循環中,我們将待排序的序列分成若幹個子序列。在第二個循環中,我們使用插入排序來對每個子序列進行排序。

插入排序的應用

插入排序在實際應用中非常廣泛,比如:

  • 資料庫中的索引排序
  • 桶排序中的排序操作
  • 快速排序中的小數組排序

下面是一個使用插入排序的例子,假設我們要對一個字元串數組按照字典序進行排序。我們可以使用插入排序來實作:

void insertion_sort(char *arr[], int n) {
    int i, j;
    char *key;
    for (i = 1; i < n; i++) {
        key = arr[i];
        j = i - 1;
        while (j >= 0 && strcmp(arr[j], key) > 0) {
            arr[j + 1] = arr[j];
            j--;
        }
        arr[j + 1] = key;
    }
}           

在這個實作中,我們使用了 strcmp 函數來比較字元串的大小。

總結

插入排序是一種非常基礎的排序算法,它的時間複雜度為O(n^2),空間複雜度為O(1),是一種穩定的排序算法。在實際應用中,插入排序非常廣泛,比如在資料庫中的索引排序、桶排序中的排序操作、快速排序中的小數組排序等等。雖然插入排序非常簡單,但是它的時間複雜度較高,在處理大規模資料時效率較低。是以,我們需要對插入排序進行優化,比如使用二分查找優化、使用希爾排序優化等等。

繼續閱讀