nlogn比较快
归并排序 Merge Sort
基本思想
log2(N) log2(8) = 3
多使用相同的空间
【算法】排序算法之归并排序
https://zhuanlan.zhihu.com/p/124356219
InsertionSort.h
#pragma once
#ifndef INC_02_MERGE_SORT_INSERTIONSORT_H
#define INC_02_MERGE_SORT_INSERTIONSORT_H
#include <iostream>
#include <algorithm>
using namespace std;
template<typename T>
void insertionSort(T arr[], int n) {
for (int i = 1; i < n; i++) {
T e = arr[i];
int j;
for (j = i; j > 0 && arr[j - 1] > e; j--)
arr[j] = arr[j - 1];
arr[j] = e;
}
return;
}
// 对arr[l...r]范围的数组进行插入排序
template<typename T>
void insertionSort(T arr[], int l, int r) {
for (int i = l + 1; i <= r; i++) {
T e = arr[i];
int j;
for (j = i; j > l && arr[j - 1] > e; j--)
arr[j] = arr[j - 1];
arr[j] = e;
}
return;
}
#endif //INC_02_MERGE_SORT_INSERTIONSORT_H
SortTestHelper.h
//
// Created by liuyubobobo on 7/16/16.
//
#ifndef INC_02_MERGE_SORT_SORTTESTHELPER_H
#define INC_02_MERGE_SORT_SORTTESTHELPER_H
#include <iostream>
#include <algorithm>
#include <string>
#include <ctime>
#include <cassert>
using namespace std;
namespace SortTestHelper {
int* generateRandomArray(int n, int range_l, int range_r) {
int* arr = new int[n];
srand(time(NULL));
for (int i = 0; i < n; i++)
arr[i] = rand() % (range_r - range_l + 1) + range_l;
return arr;
}
int* generateNearlyOrderedArray(int n, int swapTimes) {
int* arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = i;
srand(time(NULL));
for (int i = 0; i < swapTimes; i++) {
int posx = rand() % n;
int posy = rand() % n;
swap(arr[posx], arr[posy]);
}
return arr;
}
int* copyIntArray(int a[], int n) {
int* arr = new int[n];
copy(a, a + n, arr);
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 testSort(const string& sortName, void (*sort)(T[], int), T arr[], int n) {
clock_t startTime = clock();
sort(arr, n);
clock_t endTime = clock();
cout << sortName << " : " << double(endTime - startTime) / CLOCKS_PER_SEC << " s" << endl;
assert(isSorted(arr, n));
return;
}
};
#endif //INC_02_MERGE_SORT_SORTTESTHELPER_H
#pragma once
主程序
// CPlusTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include "SortTestHelper.h"
#include "InsertionSort.h"
using namespace std;
void merge(int arr[], int left, int mid, int right) {
int *aux = new int[right - left + 1];
for (size_t i = left; i < right; i++)
{
aux[i - left] = arr[i];
}
// i and j in aux array index
//k is the right order index
int i = left, j = mid + 1;
for (size_t k = left; k < right; k++)
{
if (i > mid) { arr[k] = aux[j - left]; j++; }
else if (j > right) { arr[k] = aux[i - left]; i++; }
else if (aux[i - left] < aux[j - left]) { arr[k] = aux[i - left]; i++; }
else { arr[k] = aux[j - left]; j++; }
}
delete[] aux;
}
void __mergeSort(int arr[], int left, int right)
{
if (left >= right)
return;
int mid = (left + right) / 2;
__mergeSort(arr, left, mid);
__mergeSort(arr, mid + 1, right);
merge(arr, left, mid, right);
}
void mergeSort(int arr[], int n)
{
__mergeSort(arr, 0, n - 1);
}
int main()
{
int n = 50000;
// 测试1 一般性测试
cout << "Test for Random Array, size = " << n << ", random range [0, " << n << "]" << endl;
int* arr1 = SortTestHelper::generateRandomArray(n, 0, n);
int* arr2 = SortTestHelper::copyIntArray(arr1, n);
SortTestHelper::testSort("Insertion Sort", insertionSort, arr1, n);
SortTestHelper::testSort("Merge Sort", mergeSort, arr2, n);
delete[] arr1;
delete[] arr2;
cout << endl;
测试2 测试近乎有序的数组
int swapTimes = 10;
cout << "Test for Random Nearly Ordered Array, size = " << n << ", swap time = " << swapTimes << endl;
arr1 = SortTestHelper::generateNearlyOrderedArray(n, swapTimes);
arr2 = SortTestHelper::copyIntArray(arr1, n);
SortTestHelper::testSort("Insertion Sort", insertionSort, arr1, n);
SortTestHelper::testSort("Merge Sort", mergeSort, arr2, n);
delete(arr1);
delete(arr2);
return 0;
}
void __mergeSort(int arr[], int left, int right)
{if (left >= right)
return;int mid = (left + right) / 2;
__mergeSort(arr, left, mid);
__mergeSort(arr, mid + 1, right);
merge(arr, left, mid, right);
}
这个递归函数没怎么看懂
发现当数组无序时归并算法效率高,但当数组大部分有序时归并算法效率并不高