这一章,其实主要就是3个问题。
1.插入排序
2.算法分析
3.分治法
关于插入排序:
你应该打过牌吧?那你摸牌然后整理牌的过程其实就是个插入排序。左手握牌,那么右手摸牌然后把它插入相应的位置。这就是插入排序,简单吧。看代码如下:
public class insertion_sort {
public static void insertionSort(int[] a){
int j;
for(int p=1;p<a.length;p++){
int tmp=a[p];
for(j=p;j>0&&tmp<a[j-1];j--)
a[j]=a[j-1];
a[j]=tmp;
}
}
}
这里还说到了一个重要的概念就是,循环不变式,它是用来证明我们的算法是正确的,和归纳法很相似,可以看看书p11.关于算法分析:
有两个关键概念,运行时间和输入规模。
以及,最坏情况的意义。还有平均情况的意义。
关于分治法:
分治策略:将原问题划分成n个规模较小而结构与原问题相似的子问题;递归的解决这些子问题,然后再合并其结果,就得到原问题的解。
分治策略的三步骤(P17):分解(Divide),解决(Conquer),合并(Combine)。
合并排序算法就是利用了分治策略,将n个元素分成各含n/2个元素的子序列。
它也是一种递归,可是它很特殊,不是自己调用自己,而是自己可以划分几个小问题,而这些问题又可以自己递归调用自己。最明显的例子就是,合并算法,也就是我前面说的归并算法,不过现在给大家看个java 的实例,代码如下:
public class merge_sort {
public static void mergeSort(int [] a){
int [] tmpArray=new int[a.length];
mergeSort(a,tmpArray,0,a.length-1);
}
private static void mergeSort(int[] a,int[] tmpArray,int left,int right){
if(left<right){
int center=(left+right)/2;
mergeSort(a,tmpArray,left,center);
mergeSort(a,tmpArray,center+1,right);
merge(a,tmpArray,left,center+1,right);
}
}
private static void merge(int [] a,int [] tmpArray,int leftPos,int rightPos,int rightEnd){
int leftEnd=rightPos-1;
int tmpPos=leftPos;
int numElements=rightEnd-leftPos+1;
while(leftPos<=leftEnd&&rightPos<=rightEnd)
if(a [leftPos]<=a[rgihtPos])
tmpArray[tmpPos++]=a[leftPos++];
else
tmpArray[tmpPos++]=a[rightPos++];
while(leftPos<=leftEnd)
tmpArray[tmpPos++]=a[leftPos++];
while(rightPos<=righttEnd)
tmpArray[tmpPos++]=a[rightPos++];
for(int i=0;i<numElements;i++,rightEnd--)
a[rightEnd]=tmpArray[rightEnd];
}
}
定义了3个函数,公共的mergeSort()函数它负责调用私有的mergeSort(),最后,就是merge函数,实习最后的合并。和书上的不太一样,但是算法,大家重要的是掌握里面的思想,然后,具体实现可谓千差万别。