该篇博客介绍的经典算法有:冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序
冒泡排序 Bubble Sort
概念:依次比较相邻两个元素的大小,这样一轮比较下来就可以得出当前轮的最值。
步骤:
1、比较相邻的两个元素
2、若左侧元素值较大,则交换位置
3、第i轮比较范围为[0,n-i],得到第i大元素
4、到没有交换时即说明排序完成
代码:
|
|
复杂度:
最差时间复杂度:O(n^2)
最佳时间复杂度:O(n)[需在原代码基础上加标志位优化,见下文]
平均时间复杂度:O(n^2)
优化:
1、添加标志位,当序列有序时,停止冒泡;时间复杂度提升至O(n)
2、减少遍历次数,对已经有序的部分不再遍历
拓展:
鸡尾酒排序:对冒泡排序进行改进,每次先从低到高遍历,再从高到低遍历,即来回遍历。性能上要比冒泡排序好一些。
代码:
|
|
选择排序
概念:每次从未排序部分中找出最小值,放在已排序部分后面。
步骤:
1、在未排序部分找出最小值,放在已排序部分后面
2、重复1的操作直到全部排好序
源代码:
|
|
复杂度:
最差时间复杂度:O(n^2)
最佳时间复杂度:O(n^2)
平均时间复杂度:O(n^2)
插入排序
概念:对于每个未排序数据,扫描已排序数组,并插入到合适的位置。
步骤:
1、第一个元素认为已排序
2、之后每取出一个元素,插入到已排序数组的合适位置
源代码:
|
|
复杂度:
最差时间复杂度:O(n^2)
最佳时间复杂度:O(n)
平均时间复杂度:O(n^2)
优化:
1、如果数组范围较大,可采用二分查找,找到第一个比a[i]大的位置再insert即可
希尔排序
概念:是对插入排序的高效改进,将序列每次按不同步长划分,再对每列进行插入排序,是非稳定算法
步骤:每次按不同的步长对数组进行划分行,再对每列进行插入排序,改变步长重复上面的操作,直到步长为1,即得到完全有序的数组
源代码:
|
|
复杂度:
复杂度取决于步长的选择。
归并排序
概念:采用分治法实现,将数组先分解再合并的过程中做到排序
步骤:将数组递归地分为left、right两部分,当left、right分别有序后再合并left、right即可得到排序后的数组。
源代码:
|
|
复杂度:
最差时间复杂度:O(nlogn)
最佳时间复杂度:O(n)
平均时间复杂度:O(nlogn)
快速排序
概念:每次把序列以基准划分为左右两部分,重新排列使左侧部分小于基准,右侧部分大于基准。再对基准左右两侧分别进行排序。
步骤:
1、挑出一个元素作为基准
2、重新排序,使得比基准小的元素都放在基准左侧,比基准大的元素都放在基准右侧。
3、递归地对基准左右两侧数据进行排序
源代码:
|
|
复杂度:
最差时间复杂度:O(n^2)
最佳时间复杂度:O(nlogn)
平均时间复杂度:O(nlogn)