博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
两种常用的排序算法
阅读量:6240 次
发布时间:2019-06-22

本文共 2857 字,大约阅读时间需要 9 分钟。

本文讨论两种著名且很有用的排序算法:插入排序,快速排序。

插入排序

插入排序的思想与打牌起牌类似:每次从牌堆里拿一张牌,插入到已经排好序的牌中。

具体算法描述如下:

  1. 从第一个元素开始,该元素可以认为已经被排序

  2. 取出下一个元素,从该元素开始,从后向前扫描表

  3. 如果前一个元素大于后一个元素,则交换两个元素的位置

  4. 重复步骤 3,直到前一个元素不大于后一个元素

  5. 重复步骤 2~4

现有一组数组 A = [5, 6, 3, 1, 8, 7, 2, 4],共有八个记录,排序过程如下:

[5]   6   3   1   8   7   2   4  ↑   │  └───┘[5, 6]   3   1   8   7   2   4↑        │└────────┘[3, 5, 6]  1   8   7   2   4↑          │└──────────┘[1, 3, 5, 6]  8   7   2   4           ↑  │           └──┘[1, 3, 5, 6, 8]  7   2   4            ↑    │            └────┘[1, 3, 5, 6, 7, 8]  2   4   ↑                │   └────────────────┘[1, 2, 3, 5, 6, 7, 8]  4         ↑             │         └─────────────┘ [1, 2, 3, 4, 5, 6, 7, 8]

动态过程如下:

插入排序

代码实现:

function isort(A, n, i, j, t) {    for (i = 2; i <= n; i++) {        # scan        for (j = i; j > 1 && A[j-1] > A[j]; j--) {            # swap 2 elements            t = A[j-1]            A[j-1] = A[j]            A[j] = t        }    }}# 测试代码# 每个数字占一行{ A[NR] = $0 }END {    isort(A, NR)    for (i = 1; i <= NR; i++) {        print A[i]    }}
要排序的文件:$ cat isort.txt56318724排序后输出:$ awk -f isort.awk isort.txt12345678输入倒序的10个数字:$ seq 1 10 | tac | awk -f isort.awk12345678910

算法复杂度分析:

因为有两层循环,所以算法复杂度为
$$ O(n^2)$$

快速排序

快速排序是图灵奖得主 C. R. A. Hoare 于1960 年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide and Conquer)。

分治法的基本思想是:将原问题分解为若干个规模更小但结构与原问题相似的子问题。递归地解这些子问题,然后将这些子问题的解组合为原问题的解。

步骤为:

  1. 从数列中挑出一个元素,称为"基准"(pivot),

  2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。

  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

图解可以看,讲得比较详细。

代码实现:

function swap(A, left, right, t) {    t = A[left]    A[left] = A[right]    A[right] = t}function qsort(A, left, right, pivot, i, j) {    if (left < right) {        # select a pivot element        pivot = left        i = left        j = right        while (i < j) {            # increment i till you get a number greater than the pivot element            while (A[i] <= A[pivot] && i <= right)                i++            # decrement j till you get a number less than the pivot element            while (A[j] > A[pivot] && j >= left)               j--            # if i < j swap the elements in locations i and j            if (i < j) {               swap(A, i, j)            }        }        # when i >= j it means the j-th position is the correct position        # of the pivot element, hence swap the pivot element with the        # element in the j-th position        swap(A, pivot, j)        # Repeat quicksort for the two sub-arrays, one to the left of j        # and one to the right of j        qsort(A, left, j - 1)        qsort(A, j + 1, right)    }}# 测试代码{ A[NR] = $0 }END {    qsort(A, 1, NR)    for (i = 1; i <= NR; i++) {        print A[i]    }}

和插入排序一样,测试如下:

$ cat isort.txt56318724$ awk -f qsort.awk isort.txt12345678$ seq 1 10 | tac | awk -f qsort.awk12345678910

算法复杂度分析:

平均复杂度为 $$ O(nlogn) $$

转载地址:http://zgdia.baihongyu.com/

你可能感兴趣的文章
vim显示行号、语法高亮、自动缩进的设置
查看>>
shell中的if语句
查看>>
WCf客户端测试
查看>>
Java线程面试题 Top 50
查看>>
java内存模型
查看>>
python继承关系及DVD案例
查看>>
木其工作室代写程序 [原]使用Filter过滤ip禁止访问系统
查看>>
2.6 The Object Model -- Bindings
查看>>
2.4 The Object Model -- Computed Properties and Aggregate Data with @each(计算的属性和使用@each聚合数据)...
查看>>
二叉树问题(区间DP好题)
查看>>
PHP基础
查看>>
PHP奇淫技巧
查看>>
Centos中配置环境变量
查看>>
mysql中判断记录是否存在方法比较【转】
查看>>
HBase 列族的概念
查看>>
hdu2036
查看>>
基于模板匹配的马赛克检验
查看>>
Database4.exe用来导入excel
查看>>
Unable to preventDefault inside passive event listener
查看>>
java中string和int互相转化 (转)
查看>>