前言

由于考研的原因需要复习算法课程,故在此记录下复习笔记,希望能够帮到初学算法的同学们

本笔记是基于慕课网的算法课程编写的,仅做个人记录所用

本笔记不仅仅记录各种算法的写法,还会探究每种算法的内涵,希望大家看完后都能有所收获

由于记笔记的时间较为紧张,故有些地方会略写,还望遇到我略写之处大家可以自行扩展

笔记统一使用C++语言在VS2015上编写

若有所缺漏还烦请指正!

本章简介

本章主要围绕两个最基础的O(n^2)的算法:选择排序插入排序展开

其中还包含了些许功能型函数的书写

研究后发现其实就算是O(n^2)级别的算法有自己独特的用处!

选择排序 Selection Sort

1.找出最小的数字所在的位置

2.将最小的数字与最前方的位置里的数字交换

3.再在除了最小之外的其他数字中寻找最小的数字

4.将其与第二个位置上的数字交换

5.以此类推直到结束

main函数如下:

排序算法基础笔记

选择排序函数使用模板(泛型)后修改如下:

排序算法基础笔记

观察发现,选择排序在任何情况下都要将两层循环执行完成,所以非常的慢

测试用例

新建SortTestHelper.h

SortTestHelper.h中编写函数generateRandomArray

n个元素的随机数组,范围在[rangL,rangR],返回指向第一个元素的指针

排序算法基础笔记

SortTestHelper.h中编写函数:printArray

排序算法基础笔记

SortTestHelper.h中编写测试:testSort

排序算法基础笔记

其中assert的位置要在两个colck计时之外,并且要在cout输出语句之前.才能保证既不影响计时的准确性,又能在出错时计时中止程序.

SortTestHelper.h中编写断言:isSorted

排序算法基础笔记

插入排序 Insertion Sort

1.像打扑克牌时整理排序一样

2.第一个数不动

3.第二个数跟第一个比大小,若不对则交换

4.第三个数和第二个数比,若不对则交换后跟第一个数比

5.以此类推直到结束

排序函数:

排序算法基础笔记

main函数:

排序算法基础笔记

SortTestHelper.h中添加复制数组函数:copyIntArray

排序算法基础笔记

其中C4996报错的解决方法如下:

http://blog.csdn.net/zengraoli/article/details/28910485

对比结果如图:

排序算法基础笔记

插入排序时间比选择排序还要多?

因为交换操作比比较操作更费时!

插入排序改进

思路是尽量减少交换操作,故可以变成"事先储存+多次对比+一次赋值"的形式

其中第N个元素的交换思路如下:

1.将第N个元素保存一份副本

2.与第N-1个元素比较,若比N-1小则将N-1复制到N

3.与N-2比较,类推

4.与N-i-1比较,发现N-i-1元素比N小,则将保存的副本赋值给N-i即可

其中插入排序代码修改为:

排序算法基础笔记

将swap()的三次操作变成了赋值的一次操作

并且插入排序比起选择排序有了提前终止的功能

故再次执行后对比结果如下:

排序算法基础笔记

插入排序的精髓在于提前终止,为了验证这一点我们创造一个近乎有序的数组,再观察两种排序的时间,创造近乎有序的数组的思路是:

先创造一个顺序数组,再给定次数的随机调换顺序数组中的元素即可

根据这个思路,generateNearlyOrderedArray函数如下:

排序算法基础笔记

在main函数中调用generateNearlyOrderedArray并赋值50进行测试,发现插入与选择的差距的确变大了很多:

排序算法基础笔记

总结说来,插入排序对近乎有序的数组进行排序的性能非常高

这使得其在实践中应用非常广泛,因为我们要排序的数组大多都是近乎有序的

若数组有序,则插入排序会变成O(n)级别的算法!即每个对比一次即可

扩展

希尔排序 Shell Sort是插入排序的延伸算法,具有O(nlogn)的时间复杂度

插入排序与希尔排序差别如下:

插入排序是与前一个元素比较

希尔排序是与前h个元素比较,随着h缩小到1,可以将无序数组变成近乎有序的数组,再变成有序数组,大大提升排序效率

思考

1.使用同样的方法分析优化冒泡排序 Bubble Sort

2.实现希尔排序的过程

相关文章: