版权声明:本文为博主原创文章,未经博主允许不得转载。 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需要三次赋值,而每次移动操作只需要一次赋值,所以插入操作的运行时间比选择排序长一些。