算法学习之排序

来源:互联网 发布:算法设计与分析(第2版) 编辑:程序博客网 时间:2024/05/16 05:35

由于学习缘故,将今日所学排序算法做以归纳总结,以备来日便宜:

插入排序:

public static void insertSort(int a[]){int key;for(int j = 2;j < a.length;j++){key = a[j];//insert a[j] into the sorted sequencea[1..j-1]int i = j - 1;while(i > 0 && key < a[i]){a[i + 1] = a[i];//后面大的元素往前挪i = i-1;}a[i+1] = key;//将键值插入}}

时间复杂度:T(n) = O(n(n - 1)/2) = O(n^2)

思想:边比较变排序,将数组分成排好序的和未排好序两段。

HeapSort

public void maxHeapyfy(int i)//维护一个大顶堆{if(2*i < a.length && 2*i+1 < a.length){ //System.out.print("@@@@@");int leftchild = 2*i;int rightchild = 2*i+1;int largest;if(leftchild <= heapsize && a[leftchild] > a[i])largest = leftchild;else largest = i;//System.out.print(a[rightchild]);if (rightchild <= heapsize && a[rightchild] > a[largest])largest = rightchild;//找出比较大的元素if(largest != i){//如果孩子比父亲大,就交换int temp;temp = a[i];a[i] = a[largest];a[largest] = temp;maxHeapyfy(largest);//交换完后开始协调孩子节点作为父节点的堆}}}

T(n) = O(h) = O(lgn)

public void buildHeap(){System.out.print("建堆过程:"+"\n");for(int i = (a.length - 2)/2;i >= 1;i--)//从下往上建堆{//System.out.print(a[i]);maxHeapyfy(i);for(int j = 1;j < a.length - 1;j++)System.out.print(a[j]+" ");System.out.print("***"+"\n");}}
T(n) = O(lgn)

public void heapSort()//堆排序{buildHeap();System.out.print("\n"+"建完堆后:"+"\n");for(int j = 1;j < a.length - 1;j++)System.out.print(a[j]+" ");System.out.print("*_*"+"\n"+"排序过程:"+"\n");for(int i = a.length - 2;i >= 2;i--){int t;t = a[i];//每次把第一个换到数组最后一个a[i] = a[1];a[1] = t;heapsize = heapsize - 1;for(int j = 1;j < a.length - 1;j++)System.out.print(a[j]+" ");System.out.print("\n");maxHeapyfy(1);}}

T(n) = O(lgn) + O(nlgn) = O(lgn)
数据结构:数组,用下标来维护父子关系

HeapSort的一个应用:优先队列

<span style="font-size:12px;">public int heapMaxinum()//优先队列最大值{return a[1];}public int heapExtract()//去掉并返回堆中最大{if(heapsize < 1)System.out.print("heap overflow\n");int max = a[1];a[1] = a[heapsize];heapsize--;maxHeapyfy(1);return max;}public void heapIncrease(int i,int key){if(a[i] > key)System.out.print("new key is smaller than current key\n");a[i] = key;while(i > 1 && a[i/2] < a[i])//满足比父节点要小的性质{int t = a[i];a[i] = a[i/2];a[i/2] = t;i = i/2;}}public void maxInsert(int key){heapsize = heapsize + 1;a[heapsize] = -9999;heapIncrease(heapsize,key);}</span>

MergeSort:

MergeSort(a,p,r)
if p < r
q = (p+r)/2;
MergeSort(a,p,q);
MergeSort(a,q+1,r);
Merge(a,p,r);//O(n)

T(n) = 2T(n/2) + O(n)

利用主定理:a = 2;b = 2;n^(log22) = n  == O(n)

                     case2:f(n) = O(n)*1,故k = 0;所以:T(n) = O(nlgn)

QuickSort

public static int partition(int[] a,int p,int r){//对数组a原址重排int x = a[r];//令最后一个元素为pivotint i = p - 1;for(int j = p;j <= r - 1;j++){if(a[j] <= x){i++;int t = a[i];a[i] = a[j];a[j] = t;}}int t = a[i+1];a[i+1] = a[r];//自此,pivot左边的元素均小于它,右边的均大于它a[r] = t;return i+1;}public static void quickSort(int[] a,int p,int r){if(p < r){int q = partition(a,p,r);//O(n)quickSort(a,p,q-1);quickSort(a,q+1,r);}}

pivot刚好在中间时:T(n) = 2(n/2) + O(n)  ==>  T(n) = O(nlgn)

pivot造成0:n-1时(也就是所有元素都相等或者已然排好序(自小到大)):T(n) = T(n-1) + T(0) + O(n) ==> T(n) = O(n^2)




几个排序算法比较

algorithmworst caseaverage casebest casespace coststable ?implementsInsertSortO(n^2) reverse sortedO(n^2)O(n) sortedO(1)yesinsert a[j] to sorted a[1..j-1]MergeSortO(nlgn)O(nlgn)O(nlgn)O(n)yesDC MergeSort() Merge()HeapSortO(nlgn)O(nlgn)O(nlgn)O(1)noBuliHeap()  MaxHeapify()QuickSortO(n^2) (0:n-1)O(nlgn)O(nlgn) 对半O(1)noPartition() BubbleSortO(n^2)O(n^2)O(n)O(1)yes 

0 0
原创粉丝点击