排序算法总结

2017-11-18  本文已影响0人  Miss_麦兜

基本概念

1. 时间复杂度

2. 空间复杂度

3. 稳定性

4. 测试用例

随机生成数组,用自带的sort函数进行结果验证。引用类型数据还要写比对函数。

5. 递归和迭代

基于比较的的排序

时间复杂度不可能低于O(N*logN)

一、冒泡排序

1. 原理

从第一个数开始,比较相邻的两个数,大的数往下沉,每次排好未排序序列中的最大数。

2. 交换两个数据的方法

(1)用temp变量保存。

var temp=a;
a=b;
b=temp;

(2)异或运算(XOR)。
异或满足交换律和结合律,就是无进位相加,1+0=1,0+1=1,1+1=0。
缺点:float类型且引用地址相同不能用该方法。

a=a^b;
b=a^b;
a=a^b;

3. 时间复杂度

N+N-1+....+1=N(N+1)/2;只要高阶项,不要低阶项,也不要高阶项系数,因此为O(N²)。

4. 空间复杂度

冒泡排序只需要几个有限的变量空间,所以是O(1)。

5. 稳定性

相等的不交换,大于时交换,就可以保证稳定性。

二、插入排序

1. 原理(类似扑克牌)

插入排序就是,在有序区中,从后往前,遇到大于自身的数就进行交互换,看什么时候停下来。直到最后一个数加入有序区。

2.空间复杂度

最差情况下1+...+N-1=(N-1)N/2,因此为O(N²)。

3. 空间复杂度

只需要几个有限的变量空间,所以是O(1)。

4. 稳定性

相等的不交换,只有大于时交换,就可以保证稳定性。

三、选择排序

1. 原理

每次从无序区中选择最小的数加入到有序区的末尾。与相应位置的数据进行交换

2.空间复杂度

每次遍历找最小值:N+N-1+....+1=N(N+1)/2,因此为O(N²)。

3. 空间复杂度

只需要几个有限的变量空间,所以是O(1)。

四、快速排序

logN默认以2为底,代表长度为N的数组可以二分多少次。

1、求M([3,1,5,4,2])中不在N([9,2,7])中的数的集合,即求M-N的差集

(1)暴力搜索

将M中每个数依次与N中的数进行遍历对比,不在N中就打印,在N中就直接跳过。
时间复杂度O(MN)。

(2)先排序再二分

2、随机快排原理

3、代码实现

(1)如果为null或者length<2,直接返回
(2)随机选择一个数作为基准数,交换至数组末尾
(3)partition返回等于基准数的左右边界下标,再递归的对小于区和大于区进行快排。

4、时间复杂度

(1)选一个随机的划分数,为O(1)。
(2)partition过程,将数组划分为三个区间,就是遍历一次数组的过程为O(N)。
(3)左侧和右侧分别进行了递归。

5、空间复杂度

因为左右需要递归排序,过程中需要不断记录划分值的位置,因此空间复杂度为断点树的高度,即log(2)(N)

五、归并排序

1、原理

2、小和问题

3、求逆序对

六、堆排序

关键步骤:heapInsert, heapify,堆的扩大和缩小操作

1、堆的概念

2、原理

(1)将数组变换为大根堆。每个数和父节点的值进行比较,如果大于父节点,就交换。时间复杂度=log1+log2+log3+...+logN=O(N)。
(2)此时根节点的值最大,然后交换根节点和最后一个节点,保持最后一个节点不动,size--,超过size就代表越界。然后再构建大根堆,以此往复,每次找打最大值,直至所有数据排完序。

最重要的heapinsert(初始化构建大根堆),heapify(下沉函数),size。优先级队列的题目就是堆,建立堆的过程和任何一个堆沉下去的过程重要。

4、时间复杂度

(1)建立大根堆的过程为O(N)。
(2)heapify的过程就是树的高度,为O(logN)。
(3)N个数的时间复杂度就是O(NlogN),但常数项很大。

5、堆排和快排对比

七、希尔排序

插入排序,就是步长为1的希尔排序。

八、系统中的排序原理

不基于比较的的排序

不基于比较的排序是有瓶颈的,对数据的位数和范围有限制。

桶排序

桶排序只是一个概念,基数排序和计数排序是桶排序的具体实现。

一、计数排序

先准备好相应数量的桶,然后遍历数据,将其放入对应的桶中,最后将桶中的数依次倒出来。

二、基数排序

  1. 取位数最多的记录,其他不足该位数的补0。
  2. 按照个位数字依次放入桶中。
  3. 从0号桶开始,依次倒出来。先入桶的先倒(队列结构)。
  4. 按照十位数进桶,再倒出来,如此反复,直到最高位,结束。

三、扩展

1、求排序后的最大相邻数差值

上一篇下一篇

猜你喜欢

热点阅读