算法导论-循环不变式、插入排序、归并排序

循环不变式
算法导论第二章中的原文是:We state these properties of A[1 �E j -1] formally as a loop invariant。其中举的例子是插入排序,每次循环从数组A中取出第j个元素插入有序区A[1 .. j-1],然后递增j。这样A[1 .. j-1]的有序性始终得到保持,这就是所谓的“循环不变”了。


这个概念主要用来检验算法的正确性
   1. 初始化(循环第一次迭代之前)的时候,A[1 �E j -1]的“有序性”是成立的;
  2. 在循环的每次迭代过程中,A[1 �E j -1]的“有序性”仍然保持;
  3. 循环结束的时候,A[1 �E j -1]的“有序性”仍然成立。
  
   我的理解就是:解集合中的解一定正确。每次循环之后将新的解归入解集合,直至全部数都归入解集合。


插入排序
思路:假设最前面的第一个数已排好序,循环添加后面的数,添加的时候如果被添加的数满足条件就和前面的数交换位置,最终每一个数都到达自己的位置,排序结束。T(n)=O(n^2).
#include<stdio.h> void insertSort(int *a,int n) { 	int i,j; 	for(i=1;i<=n;i++) 	{ 		int tmp=a[i]; 		j=i; 		while(j>0&&a[j-1]>tmp) 		{ 			a[j]=a[j-1]; 			j--; 		} 		a[j]=tmp; 	} 	printf("After insert-sort:\n"); 	for(i=1;i<n;i++) printf("%6d",a[i]); 	printf("\n"); } int main() { 	int a[]={1,9,3,5,23,15,8}; 	insertSort(a,7);; 	return 0; }


归并排序
思路:归并排序属于分治法的一种:把待排序的序列分为若干自序列,每个子序列都是有序的,然后把有序子序列合并为整体有序序列。T(n)=O(nlgn).

#include<stdio.h> const int maxSize=100;  void merge(int a[],int n) { 	int i,j,k=0; //将a中数据暂存在b中 int b[10]; 	for(i=0;i<n;i++) b[i]=a[i]; 	i=0,j=n/2; 	while(i<n/2&&j<n) 	{ 		if(b[i]<=b[j])a[k++]=b[i++]; 		else a[k++]=b[j++]; 	} 	if(i<n/2) 		for(;i<n/2;i++)	a[k++]=b[i]; 	if(j<n) 		for(;j<n;j++) a[k++]=b[j];  	printf("After merge-sort:\n"); 	for(i=0;i<n;i++) printf("%6d",a[i]); 	printf("\n"); } void mergeSort(int *a,int n) {     if(n>=2)     {         mergeSort(a,n/2);         mergeSort(a+n/2,n-n/2);         merge(a,n);     } } int main() {  	int a[]={27,22,18,20,15,19,12}; 	mergeSort(a,7); 	//printf("Hello!"); 	return 0; } 



你可能感兴趣的:(算法,properties,ini,merge)