冒泡bubble_sort排序:
无序 |
(每一轮元素比较VS后确定最大值,放在最后) |
- O(n^2) ,优化后O(n)
- 稳定
选择select_sort排序:
前面有序的元素,最后一个固定位置,与后面无序元素vs,选出一个放入固定位置;
- O(n^2) ,无法优化
- 不稳定
有序 | 无序 |
【固定位置,最后一个元素】 | (与无序元素比较,与无序中最小元素交换位置) |
插入insert_sort排序:
前面有序元素,后面无序元素选一个,与前面有序元素比较后确定固定的位置;
- O(n^2) ,优化后O(n)
- 稳定
有序 | 无序 |
【不确定位置,无序元素比较后插入】 | (第一个,与有序的元素比较后,插入有序中的位置) |
Shell排序:
和插入排序相近,分gap段,无序与上一个距离gap的有序去比较。
有序1 | 无序1 | 无序2 | ||
与有序1 VS | 与有序1 VS |
有序2 | 无序2 | |||
与有序2 VS |
快速quick_sort排序:
选一元素,不分有序无序,左右指针夹击,遍历找到元素的正确位置;(可能元素在一端,需要全部遍历)
左指针走过的一定<mid_value,右指针走过的一定>mid_value;但是mid_value左右的此轮不管排序是否正常。
- 正常,O(nlogn)
- 极端最坏情况O(n^2),有序序列
- 不稳定
- “分而治之”,选择后的元素左右两侧拆分,两侧分别继续找正确位置;
- 先排序在左右递归,所以只需要不断递归即可,递归结束,排序完成;无回溯处理;
- 直接对原序列alist两侧递归,变化只会在alist上,同一个列表改动;没有拆开新的值不需要合并;
quick_sort(alist,first,low-1) #(alist,first,low-1)列表指针前一部分
quick_sort(alist,low+1,last)
low | ↑ | high |
low | ⇡ | high | ↑ | low | ⇡ | high |
归并merge_sort排序:
按中轴线,两两拆分,两两合并,所以次数一定是logn;
- 正常,O(nlogn)
- 极端,O(nlogn)
- 稳定
- 递归的过程,只是在分解,没有做改动;回溯的过程在处理元素;
- 每次传入的新序列递归/调用函数自身,会产生新的值,需要用变量接收left,right(回溯赋值1);对结果left,right变量做处理, 返回新的结果return result(回溯计算2);
left = merge_sort(alist[:,mid]) #alist[:,mid]新列表
right = merge_sort(alist[mid,:]) #alist[mid,:]新列表
快速排序与归并排序区别:
快速排序与归并排序都是把数组分成子数组,进行排序。
- 归并排序,数组分成独立的子数组,分别进行排序,排序完归并,从而将整个数组排序;
- 快速排序,在原数组上排序,当数组子数组都有序,整个数组自然有序。
- 归并排序,从中间切分数组;
- 快速排序,切分数组的位置不一定在中间;