一、循环不变式的概念:
在循环结构设计中,核心设计就是找到循环结构中循环不变式(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中。