数据结构与算法C++之插入排序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/majinlei121/article/details/83756558

本篇实现的是插入排序,其算法复杂度是O(n2),插入排序的原理来自博客
插入排序原理很简单,将一组数据分成两组,分别将其称为有序组与待插入组。左边为有序组,右边为待插入组,每次从待插入组中取出一个元素,与有序组的元素进行比较,并找到合适的位置,将该元素插到有序组当中。就这样,每次插入一个元素,有序组增加,待插入组减少。直到待插入组元素个数为0。当然,插入过程中涉及到了元素的移动。为了排序方便,一般将数据第一个元素视为有序组,其他均为待插入组。然后有序组元素慢慢增加,待插入组元素慢慢减少,原理图如下
插入排序原理图
下面是C++实现:

#include <iostream>

using namespace std;

template<typename T>
void InsertionSorting(T arr[], int n){
    for (int i = 0; i < n - 1; i++){
        for (int j = i + 1; j > 0; j--){
            if (arr[j-1] > arr[j]){
                swap(arr[j-1], arr[j]);
            }
            else
                break;
        }
    }
    return;
}

int main(){
    int a[] = {10,9,8,7,6,5,4,3,2,1,0};
    int n = 11;
    InsertionSorting(a, n);
    for(int i = 0; i < n; i++){
        cout<<a[i]<<" ";
    }
    cout<<endl;
    return 0;
}

输出结果为:
在这里插入图片描述
上面只是简单的实现了11个元素排序,下面我们编写一个含有自动生成数组的函数、打印输出函数、复制数组函数、测试排序函数正确性、计时的头文件SortingHelp.h,来测试插入排序算法和上一篇的选择排序算法

//SortingHelp.h

#include <iostream>
#include <ctime>  //time()函数
#include <cstdlib> //rand()函数
#include <cassert> //assert()函数


using namespace std;

int* generateRandomArray(int n, int rangeL, int rangeR){//生成随机数组
    assert(rangeL < rangeR);
    int *arr = new int[n];
    srand(time(NULL));
    for (int i = 0; i < n; i++){
        arr[i] = rand() % (rangeR - rangeL + 1) + rangeL;
    }
    return arr;
}

template<typename T>
void printArray(T arr[], int n){//打印数组元素
    for (int i = 0; i < n; i ++){
        cout<<arr[i]<<" ";
    }
    cout<<endl; //换行
    return;
}


template<typename T>
bool isSorted(T arr[], int n){//测试排序算法是否正确
    for (int i = 0; i < n - 1; i++){
        if (arr[i] > arr[i + 1])
            return false;
    }
    return true;
}

template<typename T>
void testSorting(string sortName, void(*sorting)(T[], int), T arr[], int n){//第二个参数是传入排序函数的指针

    clock_t startClock = clock();
    sorting(arr, n);
    clock_t endClock = clock();
    assert(isSorted(arr, n));
    cout<<sortName<<" : "<<double(endClock-startClock)/CLOCKS_PER_SEC<<" s"<<endl;
    return;
}

int* copyIntArray(int arr[], int n){
    int* arr2 = new int[n];
    copy(arr, arr+n, arr2);
    return arr2;
}

template<typename T> //定义模板类型,使对各种数据类型都适用,如double,float,string
void SelectionSorting(T a[], int n){//选择排序算法
    for (int i = 0; i < n; i++){
        int minIndex = i;
        for (int j = i + 1; j < n; j++){
            if (a[j] < a[minIndex])
                minIndex = j;
        }
        swap(a[i], a[minIndex]);
    }
}

测试程序为:

#include <iostream>
#include "SortingHelp.h"

using namespace std;

template<typename T>
void InsertionSorting(T arr[], int n){
    for (int i = 0; i < n - 1; i++){
        for (int j = i + 1; j > 0; j--){
            if (arr[j-1] > arr[j]){
                swap(arr[j-1], arr[j]);
            }
            else
                break;
        }
    }
    return;
}

int main()
{
    int n = 10000;
    int *arr = generateRandomArray(n, 0, n);
    int *arr2 = copyIntArray(arr, n);
    testSorting("SelectionSorting", SelectionSorting, arr, n);
    testSorting("InsertionSorting", InsertionSorting, arr2, n);
    delete[] arr;//最后删除数组开辟的空间
    delete[] arr2;
    return 0;
}

输出为
在这里插入图片描述
因为在插入排序中用了交换swap操作,每次swap需要三次赋值,而每次移动操作只需要一次赋值,所以插入操作的运行时间比选择排序长一些。

猜你喜欢

转载自blog.csdn.net/majinlei121/article/details/83756558