一、循环不变式的概念:
在循环结构设计中,核心设计就是找到循环结构中循环不变式(loop invariant);
方法是找中间的一个普通循环迭代,同时保证满足边界条件(edge case)。
循环不变式满足的三个条件:
1. 初始化: 在初始化状态下,循环不变式保持某种性质。
2.保持性: 循环不变式的性质,在迭代的同时能够保持。
3.终止性: 循环不变式终止时,能够保证某种状态成立。
二、插入排序 (InsertSort)
插入排序:使用一种增量(incremental)求解的方法,在排好序的数组a[0...j-1]中,将元素a[j]插入,形成有序数组a[0...j];
插入排序算法具有循环不变式的性质:
1. 初始化: 仅有一个元素的数组a[0] ,是个排好序的数组。
2. 保持:排好序的数组a[0...j-1], 插入元素a[j],形成新的有序数组a[0...j].
3, 终止: a[0...len] 形成一个有序数组。 目的达到。
下面给出插入排序(insertSort)的三种实现方式, 均采用就地排序(sort in place)的方式:
代码如下:
#include <stdio.h> #include <stdlib.h> void printArray(int* a, int len); int binarySearch(int* a, int low, int high, int key); int modifiedBinarySearch(int* a, int low, int high, int key); int selectLocate(int* a, int len, int key); void insertSort(int * a, int len); void locateInsertSort(int* a, int len); void binarySearchInsertSort(int *a, int len); int main(int argc, char* argv[]) { int a[9] = {5,4,3,3,3,3,2,1,3}; int len =9; //insertSort(a, len); //locateInsertSort(a, len); binarySearchInsertSort(a, len); printArray(a, len); return 0; } void printArray(int* a, int len) { int i; for(i=0; i<len; i++) { printf("%d\t", *(a+i)); } printf("\n"); } void insertSort(int * a, int len) { int i; int j; int key; for(i=0; i<len-1; i++) { key= a[i+1]; for(j=i; j>=0 && key<a[j]; j--) { a[j+1] = a[j]; } if(j!=i) { a[j+1] = key; } } } void locateInsertSort(int *a, int len) { int i; int j; int k; int key; for(i=0; i<len-1; i++) { key = a[i+1]; k = selectLocate(a, i+1, key); for(j=i; j>=k; j--) { a[j+1] = a[j]; } if(k<=i) a[k] = key; } } void binarySearchInsertSort(int *a, int len) { int i; int j; int k; int key; for(i=0; i<len-1; i++) { key = a[i+1]; k = modifiedBinarySearch(a, 0, i, key); for(j=i; j>=k; j--) { a[j+1] = a[j]; } if(k<=i) a[k] = key; } } int selectLocate(int* a, int len, int key) { int i; for(i=len-1; i>=0 && key<a[i]; i--); return i+1; } int binarySearch(int *a, int low, int high, int key) { int mid; while(low <= high) { mid = (low + high) >> 1; if(key<a[mid]) { high = mid -1; } else if(key>a[mid]) { low = mid + 1; } else { return mid; } } return -1; } int modifiedBinarySearch(int *a, int low, int high, int key) { int mid; int top = high; int bottom = low; while(low <= high) { mid = (low + high) >> 1; if(key<a[mid]) { high = mid -1; } else if(key>a[mid]) { low = mid + 1; } else { break; } } /* if(low<=high) { while(mid<=top && a[mid]==key) mid++; return mid; } */ if(key>=a[mid]) { while(mid<=top && key>a[mid]) mid++; return mid; } if(key<a[mid]) { while(mid>=bottom && key<a[mid]) mid--; return mid+1; } }
三、总结,以上算法的实现参考了《算法导论》中的第二章。并对习题中将折半查找算法整合到insertSort中。