排序算法
各大排序算法汇总
Insertion Sort
把当前关键字插入前面已经排好序的子序列中。
public static void insert_sort(int[] array){ int n=array.length; for(int i=1;i<n;++i){ int tmp=array[i]; int j=i-1; while(j>=0&&array[j]>tmp){ array[j+1]=array[j]; j--; } array[j+1]=tmp; } }
改进的Insertion Sort
因为当前关键字的前面已经排好序,所有可以利用对半查找找到插入的位置。
稳定
Average complexity: O(n2) Best complexity: O(n)
public static void insert_sort_op(int[] array){ int n=array.length; for(int i=1;i<n;++i){ int low=0,high=i-1; int tmp=array[i]; while(low<=high){ int mid=(low+high)/2; if(array[mid]<tmp) low=mid+1; else high=mid-1; } for(int j=i-1;j>=low;--j){ array[j+1]=array[j]; } array[low]=tmp; } }
Shell Sort
Shell Sort is a generalization of a insertion sort, but it compares elements that are distant apart (by gap) rather than adjacent.
不稳定
Average complexity: O(nlog2n) or O(n3/2)
public static void shell_sort(int[] array){ int gap=array.length/2; while(gap>0){ for(int i=gap;i<array.length;++i){ int tmp=array[i]; int j=i-gap; while(j>=0&&array[j]>tmp){ array[j+gap]=array[j]; j=j-gap; } array[j+gap]=tmp; } gap=gap/2; } }
Bubble Sort
Just repeatedly swapping the adjacent elements.
稳定
O(n2)
Quick Sort
顾名思义,快就完事了
QuickSort is one of the most efficient sorting algorithms.
Like Merge sort, Quick sort also falls into the category of divide and conquer approach (分治法) of problem-solving methodology.
Algorithm
1.Find a pivot, which is regarded as the basis for comparison in a single round.
2.Start a left pointer at the first item in the array. Start a left pointer at the last item in the array.
3.While the value at the left pointer in the array is less than the pivot value, move the left pointer to the right. While the value at the right pointer in the array is greater than the pivot value, move the right pointer to the left.
5. Until the right and left pointer finally meet, and put the pivot element to where they meet.
Average complexity O(nlogn)
不稳定
Pseudocode
quicksort(A,p,r) { if (p < r) { q <- Partition(A,p,r) Quicksort(A,p,q) Quicksort(A,q+1,r) } } partition(A,p,r) x <- A[p] i <- p-1 j <- r+1 while (true) { repeat j <- j-1 until (A[j] <= x) repeat i <- i+1 until (A[i] >= x) if (i A[j] else return(j) } }
public static int Partition(int[] array, int low, int high) { int pivot = array[low]; //choose the left as pivot while(low<high){ while(high>low&&array[high]>pivot) --high; array[low]=array[high]; while(low<high&&array[low]<=pivot) ++low; array[high]=array[low]; } array[low]=pivot; return low; } // Divide array into half public static void Quick(int[] array, int low, int high) { if(low < high) { int pivot = Partition(array, low, high); Quick(array, low, pivot - 1); Quick(array, pivot + 1, high); } } public static void QuickSort(int array[], int size) { Quick(array, 0, size - 1); }
Heap Sort
1.Create a Heap (Min heap for Descending order, Max heap for ascending order)
Take Max Heap for example: each child is smaller than parent node
Find greatest child and swap with parent
2. delete the root with the element at leaf node.
The deleted element will be stored ar the last position in the sorted array.
After this operation, the property of the max heap is violated, then perform Down Adjustment to restore a new heap.
public static void MaxHeapify(int[] array, int root, int size) { //index starts from 0 int left = 2 * root + 1, largest; int right = left + 1, temp; // compare root, left and right if(left < size && array[left] > array[root]) largest = left; else largest = root; if(right < size && array[right] > array[largest]) largest = right; // if root is not the largest, swap if(largest != root) { temp = array[root]; array[root] = array[largest]; array[largest] = temp; //use recursion to check whether the subtree maintains property after swapping MaxHeapify(array, largest, size); } } public static void Build_Max_Heap(int[] array, int size) { // 0 to n/2 are parent; n/2 to n are leaf nodes for(int i = (size - 1) / 2; i >= 0; i--) MaxHeapify(array, i, size); } public static void HeapSort(int[] array, int size) { Build_Max_Heap(array, size); int temp, i; //use recursion to swap the root(largest) to the last leaf for(i = size - 1; i > 0; i--) { temp = array[0]; array[0] = array[i]; array[i] = temp; MaxHeapify(array, 0, i-1); } }
Average Complexity O(nlogn)
不稳定
Merge Sort
Merge Sort is an algorithm based on divide and conquer technique.
It works by recursively breaking down a problem into two or more sub-problems of the same or related type, until these become simple enough to be solved directly.
The solutions to the sub-problems are then combined to give a solution to the original problem.
Average complexity O(nlogn)
稳定
public static int tmp[]; //辅助数组 public static void MergeSort(int[] array){ int size=array.length; tmp=new int[size]; divide(array,0,size-1); tmp=null; } public static void divide(int[] array,int low,int high){ if(low<high){ int mid=(low+high)/2; divide(array,low,mid); divide(array,mid+1,high); Merge(array,low,mid,high); } } public static void Merge(int[] array,int low,int mid,int high){ int i,j,k; //i is the start of first subarray; j is the start of second one for(k=low;k<=high;++k){ tmp[k]=array[k]; } for(i=low,j=mid+1,k=i;i<=mid&&j<=high;++k){ //add smaller one into array if(tmp[i]<=tmp[j]) array[k]=tmp[i++]; else array[k]=tmp[j++]; } //add the remaining while(i<=mid) array[k++]=tmp[i++]; while(j<=high) array[k++]=tmp[j++]; }

浙公网安备 33010602011771号