20160721
KMP算法学习
主要参照阮老师的博客:字符串匹配的KMP算法
没有明白的是 部分匹配值表是如何得出的。观看了左程云老师在牛客的视频,大意如下:
搜索字符串为str[],
搜索字符串中每个字符对应的部分匹配值 存在p[] 中
p[0]=p[1]=0;(默认,由定义可知)
p[n]的计算与p[0]-p[n-1]有关。
计算p[n]的过程如下:
此时拍p[0]-p[n-1]均已知。
- str[p[n-1]]与str[n-1]相等否?
- 相等。则p[n]=p[n-1]+1;
- 不等。则查看 str{ p[ str[p[n-1]] }与str[n-1]是否相等?
- 相等,则p[n]= p[ str[p[n-1]] +1;
- 不等,则查看 str{ p{ str{ p[ str[p[n-1]] } } } 与str[n-1]是否相等
- 如此循环下去,直至 str[0]与str[n-1]的对比。
- 明日手工画图一副说明。
利用JAVA实现,代码如下:
20160723
堆排序
《算法导论》+麻省理工公开课
堆排序的核心在于创建一个最大堆,利用“维护最大推”的方法。
步骤:(注意,这里n从1开始,而不是0)
1.将数组A[1..n]建成最大推,此时最大元素在堆的根节点A[1],此时n=A.length
2.将A[1]与A[N]交换,则最大元素到了它要去的地方了。此时,最大推不再满足最大推的条件了,利用“维护最大堆”方法进行维护即可,但这时候n-1,即最大堆元素个数减一。
3.重复此过程,直到最大堆的元素个数从n-1降低到2.
伪代码如下:
HEAPSORT(A)//堆排序 BUILD-MAX-HEAP(A)//建最大堆 for i= A.length downto 2 exchangeA[1] with A[i] A.heap-size--; MAX-HELPIFY(A,1)//维护最大推 BUILD-MAX-HEAP(A) A.HEAP-SIZE = A.length for i=[A.lenth/2] downto 1 MAX-HEAPIFY(A,i) MAX-HEAPIFY(A,i) l= LEFT(i) r=RIGHT(i) if l<= A.heap-size and A[l]>A[i] largest=l else largest =i if r<= A.heap-size and A[r]>A[largest] largest=r if largest!=i exchange A[i] with A[largest] MAX-HEAPIFY(A,largest)
此处以题目练习(java)
题目:
对于一个int数组,请编写一个堆排序算法,对数组元素排序。 给定一个int数组A及数组的大小n,请返回排序后的数组。
代码如下:
package heapsort; public class Main { public static void main(String[] args){ int A[] = {99,25,0,1,3,2,4,8,1,7,54}; System.out.println("排序前:"); printHeap(A); HeapSort heap = new HeapSort(A); heap.Heapsort(A); System.out.println(""); System.out.println("排序后:"); printHeap(A); } private static void printHeap(int[] array){ for(int i=0;i<array.length;i++){ System.out.print(array[i]+" "); } } } package heapsort; import java.util.*; public class HeapSort { int heapsize; int heap[]; public HeapSort(){ } public HeapSort(int[] A){ this.heap= A; this.heapsize=A.length; } public void MaxHeapify(int i){ int l=2*i+1; int r = 2*i+2; int largest = i; if(l<=heapsize-1&&heap[i]<heap[l]) largest = l ; if(r<=heapsize-1&&heap[largest]<heap[r]) largest = r; if(largest!= i){ int t = heap[i]; heap[i] = heap[largest]; heap[largest] = t; this.MaxHeapify(largest); } } public void BuildMaxHeap(){ for(int i=heapsize/2-1;i>-1;i--){ MaxHeapify(i); } } public void Heapsort(int[] A){ BuildMaxHeap(); for(int i=A.length-1;i>-1;i--){ int t =A[0]; A[0] = A[i]; A[i] = t; heapsize--; MaxHeapify(0); } } }
关于堆排序,这篇文章很不错:http://www.cnblogs.com/jetpie/p/3971382.html
20160723
快速排序
快速排序的核心在于分治法。
对一个典型子数组A[p…r]排序的分治过程为三个步骤:
1.分解:A[p..r]被划分为俩个(可能空)的子数组A[p ..q-1]和A[q+1 ..r],使得A[p ..q-1] <= A[q] <= A[q+1 ..r]
2.解决:通过递归调用快速排序,对子数组A[p ..q-1]和A[q+1 ..r]排序。
3.合并。
快速排序之所以应用广泛,是在于其时间复杂度,最坏情况是O(n^2),最好情况是O(nlogn),但其平均时间复杂度更接近于O(nlogn)。空间复杂度:O(n*lgn)
算法导论一书中,证明了只要划分是常数比例,算法的运行时间均为O(nlogn)。
伪代码如下:
QUICKSORT(A, p, r) if p < r q=PARTITION(A, p, r) //关键 QUICKSORT(A, p, q - 1) QUICKSORT(A, q + 1, r) PARTITION(A, p, r) x =A[r] i=p - 1 for j = p to r - 1 if A[j] ≤ x i= i + 1 exchange A[i] with A[j] exchange A[i + 1] withA[r] return i + 1
老规矩,来道题目练练手:
题目:
对于一个int数组,请编写一个堆排序算法,对数组元素排序。 给定一个int数组A及数组的大小n,请返回排序后的数组。
代码如下:
package quicksort; public class Main { public static void main(String[] args){ int A[] = {99,12,44,81,10,23,36,47,47}; System.out.println("排序前:"); printHeap(A); QuickSort quick = new QuickSort(A); quick.quicksort(A,0,A.length-1); System.out.println(""); System.out.println("排序后:"); printHeap(A); } private static void printHeap(int[] array){ for(int i=0;i<array.length;i++){ System.out.print(array[i]+" "); } } } package quicksort; public class QuickSort { int quick[]; int quicksize; //int p,r; public QuickSort(int A[]){ this.quick = A; this.quicksize= A.length; } public int parttion(int a[],int p,int r){ int x=a[r]; int i,j; for(i=p-1,j=p;j<r;j++){ if(a[j]<=x){ i++; change(a,i,j); } } change(a,i+1,r); return i+1; } public void change(int A[],int a,int b){ int t=A[a]; A[a]=A[b]; A[b]=t; } public void quicksort(int a[],int p,int r){ if(p<r){ int q=parttion(a,p,r); quicksort(a,p,q-1); quicksort(a,q+1,r); } } }
来源:https://www.cnblogs.com/lingongheng/p/6444243.html