您的位置:首页 > 理论基础 > 数据结构算法

第2章 算法入门

2015-06-20 17:41 351 查看
2.0 引言

循环不变式

插入排序

分治法(divideandconquer)

合并排序

2.1 插入排序

排序问题描述:

输入:n个数(a1,a2,…,an)。

输出:输出序列的一个排序(即重新排序)(a‘1,a‘2,…,a‘n),使得,a‘1≤a‘2≤…≤a‘n。待排序的数也称为关键字(key)。

注意:在本书中,主要用伪代码书写的程序形式来表达算法。使用伪代码,数据抽象、模块化和错误处理等问题往往都被忽略掉了,以便更简练地表达算法的核心内容。

插入排序的工作原理与很多人打牌类似,整理手中牌时的做法差不多。在开始摸牌时,我们的左手是空的,牌面朝下放在桌上。接着,一次从桌上摸起一张牌,并将它插入到左手一把牌中的正确位置上。为了找到这张牌的正确位置,要将它与手中已有的每一张牌从右到左地进行比较,如图,无论在什么时候,左手中的牌都是排好序的,而这些牌原先都是桌上那副牌里最顶上的一些牌。



插入排序算法伪代码:

INSERTION-SORT(A)

1 for j←2tolength(A)

2 do key←A[j]

3 //InsertA[j]intothesequenceA[1..j−1]

4i←j−1

5whilei>0andA[i]>key

6doA[i+1]←A[i]

7i←i−1

8A[i+1]←key

解释:插入排序算法的伪代码是以一个过程的形式给出的,称为INSERTION-SORT。它的参数是一个数组A[1..n],包含了n个待排序的数。输入的各个数字是原地排序(sortedinplace)的,就是说这些数字都是在数组A中进行重新排序的,在任何时刻,至多只有其中的常数个数字是存储在数组之外的。

符号意义
A待排序数组
length(A)数组的长度,即数组中元素个数
A[j]数组中第j−1个元素
循环不变式与插入算法的正确性

结合伪代码INSERTION-SORT和数组A=(5,2,4,6,1,3)。



循环不变式主要用来帮助我们理解算法的正确性,对于循环不变式,必须证明它的三个性质,我们以INSERTION-SORT为例理解循环不变式。

初始化:它在循环的第一轮迭代开始之前,应该是正确的。

eg:证明在第一轮迭代开始之前,循环不变式是成立的。此时,j=2,而子数组A[1..j−1],即它只包含一个元素A[1],实际上就是最初在A[1]中的那个元素,这一个元素显然是排好序的,这样就证明循环不变式在循环的第一轮迭代开始之前是成立的。

保持:如果在循环的某一次迭代开始之前它是正确的,那么,在下一次迭代开始之前,它也应该保持正确。

eg:第二个性质就是证明每一轮循环都能使循环不变式保持成立。对于INSERTION-SORT我们依赖于非形式化的分析,来证明第二个性质对于外层for循环是成立。假设第j次循环,A[1..j−1]子数组由于INSERTION-SORT内部while循环保证了其子数组的有序,那么第j次循环时,循环不变式依然保持成立。

终止:当循环结束时,不变式给了我们一个有用的性质,它有助于表明算法是正确的。

eg:最后,分析一下循环结束时的情况。对于插入排序来说,当j大于n时(即当j=n+1),外层for循环结束。此时子数组A[1..n]就是整个原先的数组且已经排好序了。

2.2 算法分析

算法分析即指对一个算法所需要的资源进行预测。内存、通信带宽或计算机硬件等资源偶尔会是我们主要关心的,但通常,资源是指我们希望测度的计算时间。一般而言,对于一个给定的问题,通过分析几种候选算法,可以很容易地从中选出一个最有效的算法。

插入排序算法的分析(重点)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息