C++算法恢复训练之插入排序

插入排序是一种简单的排序算法,它的思想是将待排序的数组分为两个部分:已排序部分和未排序部分。每次从未排序部分取出一个元素,插入到已排序部分的适当位置,使得插入后的数组仍然有序。

下面是一个用 C++ 实现的插入排序的例子:

#include <iostream>
#include <vector>

using namespace std;

void insertionSort(vector<int>& array)
{
    
    
    const auto n = array.size();
    if (n < 2)
    {
    
    
        return;
    }

    for (unsigned int i = 1; i < n; ++i)
    {
    
    
        for (int j = i - 1; j >= 0; j--)
        {
    
    
            if (array[j] > array[j + 1])
            {
    
    
                const int temp = array[j + 1];
                array[j + 1] = array[j];
                array[j] = temp;
            }
        }
    }
}

int main(int argc, char* argv[])
{
    
    
    // Create an array to test sort method
    vector<int> array = {
    
    2, 3, 4, 0, 7};

    cout << "Before sorting: ";
    for (int i = 0; i < array.size(); ++i)
    {
    
    
        cout << array[i] << " ";
    }
    cout << endl;

    insertionSort(array);

    cout << "After sorting: ";
    for (int i = 0; i < array.size(); ++i)
    {
    
    
        cout << array[i] << " ";
    }
    cout << endl;

    return 0;
}

在这个例子中,我们定义了一个名为 insertionSort 的函数来实现插入排序。首先,我们判断数组的大小,如果数组大小小于 2,则直接返回,因为数组中只有一个或者没有元素时,已经是有序的了,不需要排序。然后,我们从数组的第二个元素开始遍历,因为一个元素的数组已经有序了。对于每个未排序的元素,我们将其插入到已排序的元素中,以保持整个数组的有序性。在内层循环中,我们从当前元素的前一个元素开始向前遍历已排序的元素,找到合适的位置将当前元素插入。如果当前元素比已排序的元素小,则将已排序的元素后移一位,直到找到合适的位置。找到合适的位置后,我们将当前元素插入到已排序的元素中,即将当前元素与已排序的元素后面的元素依次向后移动一位,然后将当前元素插入到空出的位置中。外层循环结束后,整个数组已经有序了,排序完成。

在最坏情况下,也就是数组本来就是逆序排列的情况下,需要进行 n − 1 n-1 n1 轮比较和移动,每轮需要比较 i 次,因此总的比较次数为

( n − 1 ) + ( n − 2 ) + . . . + 1 = n ∗ ( n − 1 ) / 2 (n-1) + (n-2) + ... + 1 = n*(n-1)/2 (n1)+(n2)+...+1=n(n1)/2

O ( n 2 ) O(n^2) O(n2)。在最好情况下,也就是数组已经有序的情况下,只需要进行 n − 1 n-1 n1 次比较,因此时间复杂度为 O ( n ) O(n) O(n)

空间复杂度的分析:插入排序是一种原地排序算法,不需要额外的存储空间,因此空间复杂度为 O ( 1 ) O(1) O(1)

总结来说,插入排序算法的优点在于对于小规模数据的排序非常高效,并且在已经接近有序的数组中表现良好。但是,对于大规模数据的排序,插入排序的效率比较低下,因为它的时间复杂度为 O(n^2),不如快速排序、归并排序等算法。因此,在实际应用中,需要根据具体的情况选择合适的排序算法。

猜你喜欢

转载自blog.csdn.net/xcinkey/article/details/129941898