ALGORITHMS
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);
}
}
}