标签:介绍 没有 div key 进入 导出 main into 移动
1 INSERTION - SORT (A)
2 for j= 2 to A.length 3 key = A[j] 4 // Insert A[j] into the sorted sequence A[1..j-1] 5 i = j - 1 6 while i>0 and A[i]>key 7 A[i+1]=A[i] 8 i = i - 1 9 A[i+1] = key
首先,算法导论书上的类代码如上述.
首先要理解的是,算法导论上的类代码并不是从 0 开始 ,而是从 1 开始的, 因此不要奇怪为何 第一行是 从 j = 2开始循环,
当然<<算法导论>>上也介绍了 循环不变式 的三条性质: 初始化 , 保持, 终止 .
根据<<算法导论>>上的内容我们用本个算法来理解一下.
初始化:循环的第一次迭代之前,它为真.
初始化:还没有进入 第一次迭代 (j=2) 前的数组 , 你可以理解为 , 断点在第 5 行末端 ( 因为这时候没有进行迭代和比较) ,这时候 子数组A[1..j-1] 仅有 A[1]这个元素 ,它自然是满足性质, 因此为真
保持:如果循环的某次迭代之前它为真,那么下次迭代之前它仍为真
保持:一般的,如果在某次迭代前 , 该数组 通过之前的迭代后,描述的性质不变 , 那么在下次迭代后 ,该数组的性质仍然不变
终止:在循环终止时,不变式为我们提供一个有用的性质,该性质有助于证明该算法是正确的.
终止:这时候算法已经排序了整个数组,并且按序排序,所以该算法是正确的.
其实,这有点像,有点像,有点像(重要的说三次)我们学的数学归纳法:
Step 1 : 命题 n = 1 时成立;
Step 2 : 假设 n = m 时 命题也成立 ,可以推导出 n = m + 1 时 也成立
Step 3 : 归纳
虽然两种方法一个用于数学推理,一个用于算法排序,用途完全不一样,但是有点相似的地方,希望能带来一些启发,当然这个比喻似乎不太恰当.
书上的练习 2.1 - 1改
A = {31, 41, 59, 26, 41, 58} 使用 INSERTION - SORT排序
1 #include <iostream> 2 using namespace std; 3 int main() 4 { 5 int A[] = { 31, 41, 59, 26, 41, 58,‘\0‘ }; 6 for (size_t j = 1;A[j] ; j++){ 7 int key = A[j]; 8 int i = j - 1; 9 while (i >= 0 && A[i] > key) { 10 A[i + 1] = A[i]; 11 i = i - 1; 12 } 13 A[i + 1] = key; 14 } 15 for (size_t i = 0; i < 7; i++){ 16 cout << A[i] << endl; 17 }
18 return 0; 19 }
9~ 13行的意思是 大于则往前移动,直到不满足条件,这时候插入
显示结果:
1 26 2 31 3 41 4 41 5 58 6 59 7 0
第一次写博客,选个比较容易的
标签:介绍 没有 div key 进入 导出 main into 移动
原文地址:https://www.cnblogs.com/zamkite/p/13335400.html