【liuyubobobo-算法与数据结构】第二章 排序基础

【liuyubobobo-算法与数据结构】第二章 排序基础,第1张

【liuyubobobo-算法与数据结构】第二章 排序基础

持续学习&持续更新中…

守破离


【liuyubobobo-算法与数据结构】第二章 排序基础
    • 说明
    • 为什么要学习O(n ^ 2)的排序算法
    • 准备工作
        • sort_helper.h
        • main函数
    • 选择排序 O(n ^ 2)
        • 排序过程—动画演示
        • 实现
    • 插入排序 O(n ^ 2)
        • 排序过程—动画演示
        • 实现
        • 排序过程—改进—动画演示
        • 改进—实现
    • 参考

说明
  • 默认从小到大进行升序排序。
  • 什么是小,什么是大,是可以自定义的。
  • 你认为什么是大,什么就是大;你认为什么是小,什么就是小。
  • 因此,升序排序就是降序排序;降序排序同样也是升序排序。
为什么要学习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 
#include 
#include 

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 
#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++版.


本文完,感谢您的关注支持!


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5659084.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存