常见排序算法(C语言实现)

排序算法源码

排序算法是《数据结构与算法》中最基本的算法之一。

对于排序算法,不能简单的就学习其代码实现而是要学习如何去分析算法,了解每一个算法的时间复杂度,空间复杂度等特征。
排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因为排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。用一张图概括:
常见排序算法(C语言实现)_第1张图片

下面以正序排列为例,介绍各个算法的实现原理

冒泡排序

算法步骤

  • 比较相邻的元素,如果左边的元素大于右边的元素就交换两个元素,否则则保持不变
  • 从最开始的一对到最后的一对,每一对都做第一步的比较运算,当遍历完整个数组时,最后一个元素就是整个数组中最大的值
  • 除了最后一个元素,其他所有元素都重复上述步骤
  • 对没有排序的元素持续重复上述步骤,直到找到最小的元素

动图演示

插入排序

算法步骤

  • 将数组分成两个部分,左边的当成有序数列,右边的为未排序的数列
  • 开始时将第一个元素当成有序数列
  • 从第二个元素开始依次遍历未排序数组接下来的元素,将扫描到的每一个元素都插入到有序数组合适的位置

动图演示

选择排序

算法步骤

  • 同插入排序一样,选择排序也将整个数组分成有序数组和未排序数组两个部分。但是与插入排序不同的是,选择排序默认数组中的所有元素都是未排序的
  • 首先在未排序数组中找到最小的元素,然后与有序数组的队尾值交换(有序数组的队尾值表示有序数组中最后一个元素的下一个元素)
  • 重复第二步,指导所以元素都完毕

Note:

在第二步交换元素这一步骤中就决定了该排序算法是不稳定的排序算法

动图演示

归并排序(递归实现)

归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

作为一种典型的分而治之思想的算法应用,归并排序的实现由两种方法:

  • 自上而下的递归(Top-down)(所有递归的方法都可以用迭代重写,所以就有了第 2 种方法);
  • 自下而上的迭代(Bottom-up);

和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是 O(nlogn) 的时间复杂度。代价是需要额外的内存空间。

在这里只介绍归并算法的递归实现

算法步骤

  • 申请空间,使其大小为两个已经排序序列之和**,该空间用来存放合并后的序列

  • 设定两个指针,最初位置分别为两个已排序序列的起始位置

  • 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

  • 重复步骤3直到某一指针到达序列尾

  • 将另一序列剩下的所有元素直接复制到合并序列尾

Note:

需要申请额外的空间来存放合并后的序列

动图演示

快速排序(递归实现)

算法步骤

  • 从数列中找出一个元素作为基准(pivot)
  • 比基准小的元素放在基准前面,比基准大的元素放在基准后面(相同的数可以放在任意一边)。遍历完一遍之后,该基准就处于数组中间位置。我们把这个称谓分区(partition)操作
  • 递归(recursive):把小于基准值元素的子数列和大于基准值元素的子数列排序重复上述步骤

递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。当子数列只有一个元素时,退出该级函数,返回上一级函数

动图演示

你可能感兴趣的:(数据结构与算法,数据结构,算法,排序算法,快速排序)