2.1插入排序
伪代码与真代码的区别在于,伪代码我们使用最简洁、最清晰的表示方法来说明给定的算法。这样的原则下,在伪代码中就会出现英语。
插入排序的特点:1、少量元素时,是一种有效的算法;2、直观想象:按顺序排扑克牌;3、是一种原址排序算法,即在同一个数组中完成排序工作,注意:在任何时刻,已经排好序的部分还是原来的数,只不过顺序已经排好而已。下面是伪代码:
//INSERTION-SORT for j = 2 to A.length key = A[j] i = j - 1 while i > 0 and A[i] > key A[i+1] = A[i] i = i - 1 A[i+1] = key
什么是循环不变式?
自己理解:在循环进行中保持性质不变。
循环不变式主要是用来帮助我们理解算法的正确性,非常类似于 数学归纳法。
类似地,关于循环不变式需要证明下面的性质:
1、初始化:循环的第一次迭代之前,它为真;(归纳法中基本情况)
2、保持:如果循环的某次迭代之前它为真,那么下次迭代之前它仍为真;(一个归纳步)
3、终止:在循环终止时,不变式为我们提供一个有用性质,该性质有助于证明算法的正确性。
伪代码中的一些约定:
1、缩进表示块结构。
2、while、for、repeat-until等循环结构以及if-else等条件结构与一般语言的意义无异。在循环计数器大于1时,后面加by。
3、//表示注释
4、i = j = e的多重赋值赋给i和j。
5、变量是局部变量。
6、数组通过“数组名[下标]”的形式来访问。
7、复合数据通常被组织成对象,对象又由属性组成。对象名后跟一个点再跟属性名,是访问对象的特定属性。我们把表示一个数组或对象的变量看做指向表示数组或对象的数据的一个指针。在赋值y=x以后,x、y指向相同的对象,修改x或者y,另一个同步变化。
8、我们按值把参数传递给过程:被调用过程接收其参数本身的副本。如果它对某个参数赋值,调用过程看不到这种变化。当对象被传递时,指向表示对象数据的指针被复制,而对象的属性却未被复制。例如,如果x是某个被调用过程的参数,在被调用过程中的赋值x=y对调用过程是不可见的。然而,赋值x.f=3却是可见的。类似地,数组通过指针来传递,结果指向数组的一个指针被传递,而不是整个数组,单个数组元素的改变调用过程是可见的。
9、一个return语句立即将控制返回到调用过程的调用点。需要注意的是,return可以返回多个值。
10、布尔运算法“and”和“or”是短路的,也就是说,求值表达式“x and y”时,先判断x,再判断y,如果x为false,那么将不再判断y。
11、关键词error表示因为已被调用的过程情况不对而出现了一个错误。但是并不说明如何处理改错误。
下面写出插入排序的c++代码(以后写的代码可能会比较幼稚):
//INSERTION-SORT,c++
#include <iostream> using namespace std; int main() { int a[10] = {10,9,8,7,6,5,4,3,2,1}; int key = 0; int i = 0,j; for(j = 1;j < 10;j++) { key = a[j]; i = j - 1; while(i >= 0 && a[i] > key) { a[i+1] = a[i]; i = i - 1; } a[i+1] = key; } for(i = 0;i < 10;i++) cout << a[i] << endl; return 0; }