术语说明
-
稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面;
-
不稳定:如果a原本在b的前面,而a=b,排序之后a可能会出现在b的后面;
例如:数组{1,2,3,3,4,7,6}。如果排序后,两个3的位置没有发生变化就是稳定;若两个3发生了调换就是不稳定 -
ln-place:占用常数内存,不占用额外内存。例如选择排序只需要占用1个内存空间交换元素即可,不需要额外申请内存空间
-
Out-place:不仅占用常数内存,还需要占用额外内存。例如基数排序
-
时间复杂度:一个算法执行所耗费的时间。
-
空间复杂度:运行完一个程序所需内存的大小。
排序的算法有很多,大致可以分类如下:
- 插入类排序:直接插入排序、希尔排序。
- 交换类排序:冒泡排序、快速排序。
- 选择类排序:简单选择排序、堆排序。
- 归并排序。
- 基数排序。
插入排序
直接插入排序是一种简单的排序方法,具体做法是:在插入第i个关键码时k1,k2,
ki-1已经排好序,这时将关键码k依次与关键码ki-1,ki-2等进行比较,找到ki应该插入的位置时停下来,将插入位置及其后的关键码依次向后移动,然后插入k。
插入排序就如图:有1点、2点、4点的牌,接下来有一张3点的牌需要将插入进去。计算机不会和人类一样肉眼看到后就插到2和4之间的。需要和4比较,和2比较后将4后移,插入到2和4之间
要注意的是,前提条件是前i-1个元素是有序的,第i个元素依次从第i-1个元素往前比较,直到找到一个比第i个元素值小的元素,而后插入,插入位置及其后的元素依次向后移动,本质是插入排序。
上图中,59依次向前比较,先和68比较,再和57比较,发现57比他小,才插入。
希尔排序
希尔排序的基本思想是:先将整个待排记录序列分割成若干子序列,然后分别进行直接插入排序,待整个序列中的记录基本有序时,再对全体记录进行一次直接插入排序。
具体做法是:
先取一个小于的整数d1,作为第一个增量,把文件的全部记录分成d1个组,即将所有距离为d1倍数序号的记录放在同一个组中,在各组内进行直接插入排序:然后取第二个增量d2(d2<d1),重复上述分组和排序工作,依此类推,直到所取的增量di=1(di<di-1<.…<d2<d1),即所有记录放在同一组进行直接插入排序为止。
希尔排序是对直接插入排序算法的改进,适合于大数据的排序,采用分组的方法,可以提高效率
为什么不直接进行插入排序呢?插入排序在元素几乎有序的情况下,效率是会增加的。也就意味着我们花很大功夫去分组排序都是为了最后一次的排序进行铺垫,它把整个序列排成近乎有序,然后对它进行最后一次插入排序,这样的效率会比较好。
增量序列(5,3,1)的值怎么设置?最后一个值肯定是1,因为最后一次要对每个元素进行一次完整的排序。最大的值至少要分成两块。如果我们的初始序列很长,那么我们的增量序列就不仅仅只有3个元素了,可能是5、7、9个元素。
简单选择排序
n个记录进行简单选择排序的基本方法是:通过n-i(1≤i≤n)在次关键字之间的比较,从n-+1个记录中选出关键字最小的记录,并和第i个记录进行交换,当i等于时所有记录有序排列。
本质就是每次选择出最小的元素进行交换,主要是选择过程,最值的交换过程只有一次。示例如下:
注意:每次都是拿着下标最小的元素进行比较,即上图第二次排序:68和59交换位置后,接下来是拿59和后面的元素进行比较。
堆排序
堆排序)(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点
堆排序的方法可分为两步:
- 依据给出的待排序关键字建立初始堆,如果是升序就是
小顶堆
,降序就是大顶堆
。
构建二叉树,根部元素是最大是降序,根部元素最小是升序 - 把最后一个元素输入到堆顶,并调整堆。重复上述步骤。
降序->大顶堆
步骤1:创建初始堆
- 首先将给出的数组{1,3,4,5,72,6,8,0}按完全二叉树规则健立图1.1
- 而后,找到此完全二叉树的最后一个非叶子节点(也即最后一颗子树),比较此叶子节点和其两个孩子结点的大小,若小,则与其孩子结点中最大的结点进行交换,如图1.2所示;
- 依据此规则再去找倒数第二个非叶子节点;
- 这是只有一层的情况,当涉及到多层次时,如图1.3和1.4所示,将3交换下来,又打破了之前的堆,因此,又要进行变换,如图1.5所示
- 之后,就按上述规则依次对非叶子节点进行变换。
可以得到最大值8。将8放到一个新的序列(待排序)里面去。然后把最尾部(0)放到首位(原来8的位置)。重新构建一次大顶堆
升序->小顶堆
步骤2:把最后一个元素输入到堆顶
- 由图可知,取走堆顶元素后,将堆中最后一个元素移入堆顶
- 而后,按照初始建堆中的方法与其孩子结点比较大小,依次向下判断交换成为一个新的堆,再取走堆顶元素
- 重复此过程。
堆排序适用于在多个元素中找出前几名的方案设计,因为堆排序是选择排
序,而目选择出前几名的效率很高。找最大的几个或者最小的几个效率还是不错的
冒泡排序
n个记录进行冒泡排序的方法是:首先将第一个记录的关键字和第二个记录的关键字进行比较,若为逆序,则交换这两个记录的值,然后比较第二个记录和第三个记录的关键字,依此类推,直到第n-1个记录和第个记录的关键字比较过为止。上述过程称为第一趟冒泡排序,其结果是关键字最大的记录被交换到第个记录的位置上。然后进行第二趟冒泡排序,对前n-1个记录进行同样的操作,其结果是关键字次大的记录被交换到第n-1个记录的位置上。最多进行n-1趟,所有记录有序排列。若在某趟冒泡排序过程没有进行相邻位置的元素交换处理,则可结束排序过程。
可以从左到右开始比较,也可以从右到左开始比较。上图是从右到左开始比较的
本质是从最后两个元素开始进行比较,将较小的元素交换到前面去,依次进行比较交换。较小的气泡浮到水面上。
选择排序是拿着一个元素和后面的每一个元素进行比较
冒泡排序是两两相邻的元素进行比较