持续学习&持续更新中…
守破离
【liuyubobobo-算法与数据结构】第二章 排序基础
说明
- 默认从小到大进行升序排序。
- 什么是小,什么是大,是可以自定义的。
- 你认为什么是大,什么就是大;你认为什么是小,什么就是小。
- 因此,升序排序就是降序排序;降序排序同样也是升序排序。
为什么要学习O(n ^ 2)的排序算法
准备工作
sort_helper.h
#pragma once
#ifndef LEARN_ALGO_AND_DS_WITH_LIUYUBO_SORT_HELPER
#define LEARN_ALGO_AND_DS_WITH_LIUYUBO_SORT_HELPER
#include <iostream>
#include <ctime>
#include <cassert>
namespace sort_helper {
//[rangeL, rangeR]
int* generateRandomArray(int count, int rangeL, int rangeR) {
assert(count > 0);
assert(rangeL <= rangeR);
int* array = new int[count];
int delta = rangeR - rangeL + 1;
srand(time(NULL));
for (int i = 0; i < count; i++) {
array[i] = rand() % delta + rangeL;
}
return array;
}
int* generateNearlyOrderedArray(int count, int swapTimes) {
assert(count > 0);
assert(swapTimes > 0);
int* array = new int[count];
for (int i = 0; i < count; i++) {
array[i] = i;
}
srand(time(NULL));
for (int i = 0; i < swapTimes; i++) {
int randomA = rand() % count;
int randomB = rand() % count;
std::swap(array[randomA], array[randomB]);
}
return array;
}
int* copyArray(int* arr, int length) {
int* array = new int[length];
for (int i = 0; i < length; i++) {
array[i] = arr[i];
}
return array;
}
void printlnArray(int array[], int length) {
if (1) return;
for (int i = 0; i < length; i++) {
std::cout << array[i] << ' ';
}
std::cout << std::endl;
}
void printlnArrayWithInfo(const char* info, int array[], int length) {
if (1) return;
std::cout << info;
printlnArray(array, length);
}
bool isArcOrderArray(int array[], int length) {
assert(array != NULL);
assert(length > 0);
for (int i = 1; i < length; i++) {
if (array[i - 1] > array[i]) return false;
}
return true;
}
void assertIsArcOrderArray(int array[], int length) {
//bool flag = isArcOrderArray(array, length);
//if (!flag) {
// cout << "测试未通过!" << endl;
//}
assert(isArcOrderArray(array, length));
}
void testSortArray(const char* info, void(*fun)(int[], int), int* arr, int length) {
int* array = sort_helper::copyArray(arr, length);
clock_t startTime = clock();
fun(array, length);
clock_t endTime = clock();
std::cout << info << " 耗时:" << ((double)(endTime - startTime)) / CLOCKS_PER_SEC << "s -> ";
printlnArray(array, length);
assertIsArcOrderArray(array, length);
delete[] array;
}
}
#endif // !LEARN_ALGO_AND_DS_WITH_LIUYUBO_SORT_HELPER
main函数
#include <iostream>
#include "sort_helper.h"
int main() {
int count = 10000;
//int rangeL = 1;
//int rangeR = 10000;
//int* array = sort_helper::generateRandomArray(count, rangeL, rangeR);
int* array = sort_helper::generateNearlyOrderedArray(count, 100);
sort_helper::printlnArrayWithInfo("original : ", array, count);
sort_helper::testSortArray("selectionSort", selectionSort, array, count);
sort_helper::testSortArray("insertionSort1", insertionSort1, array, count);
sort_helper::testSortArray("insertionSort2", insertionSort2, array, count);
sort_helper::printlnArrayWithInfo("original : ", array, count);
delete[] array;
return 0;
}
选择排序 O(n ^ 2)
- 排序前:
- 排序后:
排序过程—动画演示
实现
void selectionSort(int array[], int length) {
for (int i = 0; i < length; i++) {
int minIndex = i;
for (int j = i + 1; j < length; j++) {
if (array[j] < array[minIndex]) {
minIndex = j;
}
}
std::swap(array[minIndex], array[i]);
}
}
插入排序 O(n ^ 2)
- 对于一个近乎有序的数组来说,插入排序的性能很好,甚至会好于O(logn)级别的排序算法。
- 因此插入排序有很重要的实际意义。
- 因为很多时候我们处理的真实的数据就是近乎有序的。
- 插入排序还可以使用二分搜索进行优化。
- 插入排序还是希尔排序的底层排序。
- 插入排序在最优的情况下,也就是说我们要排序的内容是一个完全有序的数组时,插入排序就会变为**O(n)**级别的算法。
排序过程—动画演示
实现
void insertionSort1(int array[], int length) {
for (int i = 1; i < length; i++) {
int currentIndex = i;
while (currentIndex > 0 && array[currentIndex] < array[currentIndex - 1]) {
std::swap(array[currentIndex], array[currentIndex - 1]);
currentIndex--;
}
}
}
排序过程—改进—动画演示
改进—实现
void insertionSort2(int array[], int length) {
for (int i = 1; i < length; i++) {
int currentIndex = i;
int currentElement = array[currentIndex];
while (currentIndex > 0 && currentElement < array[currentIndex - 1]) {
array[currentIndex] = array[currentIndex - 1];
currentIndex--;
}
array[currentIndex] = currentElement;
}
}
参考
liuyubobobo: 算法与数据结构-综合提升 C++版.
课程代码仓库: 算法与数据结构-综合提升 C++版.
本文完,感谢您的关注支持!