常见排序算法
说明:一下的排序中,都是从数组下标为1的元素开始的,输入文件的第一个数位要排序的元素的个数n,后面n行为各个元素
一:快速排序
思路:对于要排序的数组arr,从arr[i]出分成两部分,arr[i]之前的元素都小于arr[i],之后的都大于arr[i],递归此过程直到不可再分
package algorithm.sort; import java.io.File; import java.io.FileNotFoundException; import java.util.Random; import java.util.Scanner; public class QuickSort { private static int n; public static void main(String[] args) throws FileNotFoundException { Scanner scan = new Scanner(new File("Sort")); n = scan.nextInt(); int []arr = new int[n+1]; for(int i=1;i<=n;i++){ arr[i] = scan.nextInt(); } quickSort(arr,1,n); for(int i=1;i<=n;i++){ System.out.println(arr[i]); } } private static void quickSort(int[] arr, int p, int r) { if(p<r){ int q = randoizedPartation(arr,p,r); quickSort(arr,p,q-1); quickSort(arr,q+1,r); } } private static int partation(int[] arr, int p, int r) { int x = arr[r]; int signal = p-1; for(int i=p;i<r;i++){ if(arr[i]<=x){ signal++; swap(arr,i,signal); } } swap(arr, signal+1,r); return signal+1; } public static int randoizedPartation(int[] arr, int p, int r){ Random random = new Random(); int i = random.nextInt(r-p); i += p; swap(arr, i, r); return partation(arr, p, r); } private static void swap(int[] arr, int i,int j) { int temp; temp = arr[j]; arr[j]=arr[i]; arr[i]=temp; } }
二:堆排序
思路:通过数组构造一颗二叉树,对于元素arr[i],他的做孩子是arr[2*i],右孩子是arr[2*i+1],且arr[i]大于他的左孩子和右孩子。然后从根开始取元素,取出的就是当前最大的,取出之后,和最后一个元素arr[n]交换位置,并置n=n-1,因为交换后可能已经不满足前面的条件了,所以,对新的根节点进行处理,使新的树形结构满足条件;重复此步骤,直到n=1
package algorithm.sort; import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class HeapSort { private static int n; public static void main(String[] args) throws FileNotFoundException { Scanner scan = new Scanner(new File("Sort")); n = scan.nextInt(); int []arr = new int[n+1]; for(int i=1;i<=n;i++){ arr[i] = scan.nextInt(); } heapSort(arr); for(int i=1;i<=n;i++){ System.out.println(arr[i]); } } private static void heapSort(int[] arr) { buildHeap(arr); int length = arr.length-1; int curr = length; for(int i=length;i>1;i--) { swap(arr,i,1); curr--; maxHeapify(arr,1,curr); } } private static void maxHeapify(int[] arr, int i,int stop) { if(2*i+1>stop) return; int l = 2*i; int r = 2*i+1; int largest = i; if(arr.length >=l && arr[l]>arr[i]){ largest = l; } if(arr.length >=r && arr[r]>arr[largest]){ largest = r; } if(largest != i){ swap(arr, i,largest); maxHeapify(arr, largest,stop); } } private static void swap(int[] arr, int i,int j) { int temp; temp = arr[j]; arr[j]=arr[i]; arr[i]=temp; } private static void buildHeap(int[] arr) { for(int i=(arr.length-1)/2;i>=1;i--){ maxHeapify(arr, i,arr.length-1); } } }
三:插入排序
思路:对于每个新插入的数,与前面的进行比较排序,放入合适的位置,这样保证了每次一个新的元素插入的时候,前面所有的元素都是排好序的,它只要找到自己的位置,也就完成了排序
package algorithm.sort; import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class InsertSort { private static int n; public static void main(String[] args) throws FileNotFoundException { Scanner scan = new Scanner(new File("Sort")); n = scan.nextInt(); int []arr = new int[n]; for(int i=0;i<n;i++){ arr[i] = scan.nextInt(); } sort(arr); for(int i=0;i<n;i++){ System.out.println(arr[i]); } } private static void sort(int[] arr) { for(int i=1;i<n;i++){ int j=i-1; while(j>=0 && arr[i]<arr[j] ){ j--; } int temp = arr[i]; for(int k=i;k>j+1;k--){ arr[k]=arr[k-1]; } arr[j+1]=temp; } } }
四:合并排序
思路:将一个排序递归的分成几个子排序,直到不可再分,然后对分开的数组进行合并,合并完成后的结果就是排序好的数组
package algorithm.sort; import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class MergeSort { private static int n; public static void main(String[] args) throws FileNotFoundException { Scanner scan = new Scanner(new File("Sort")); n = scan.nextInt(); int []arr = new int[n]; for(int i=0;i<n;i++){ arr[i] = scan.nextInt(); } mergesort(arr,0,n-1); for(int i=0;i<n;i++){ System.out.println(arr[i]); } } private static void mergesort(int[] arr, int p, int r) { if(p<r){ int q = (p+r)/2; mergesort(arr,p,q); mergesort(arr,q+1,r); merge(arr,p,q+1,r); } } private static void merge(int[] arr, int p, int q, int r) { int []temp = new int[r+1]; int tempp = p; int tempq = q; int c = p; while(p<tempq && q<=r){ if(arr[p] < arr[q]){ temp[c++] = arr[p++]; }else{ temp[c++] = arr[q++]; } } if(p>=tempq){ for(int i = q;i<=r;i++){ temp[c++] = arr[i]; } }else{ for(int i = p;i<q-1;i++){ temp[c++] = arr[i]; } } for(int i = tempp;i<=r;i++){ arr[i] = temp[i]; } } }
五:计数排序
思路:对于一组输入,如果满足条件arr[i]<k,则可以进行计数排序。基本思想是对每一个输入元素x,确定出比他小的元素的个数。
package algorithm.sort; import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class CountingSort { private static int n; private static int k; public static void main(String[] args) throws FileNotFoundException { Scanner scan = new Scanner(new File("countingSort")); k = scan.nextInt(); n = scan.nextInt(); int []arr = new int[n+1]; for(int i=1;i<=n;i++){ arr[i] = scan.nextInt(); } countingSort(arr); /*for(int i=1;i<=n;i++){ System.out.println(arr[i]); }*/ } private static void countingSort(int[] arr) { int []arr_c = new int[k+1]; int []arr_b = new int[arr.length]; for(int i=1;i<arr.length;i++){ arr_c[arr[i]]++; } for(int i=1;i<=k;i++){ arr_c[i]+=arr_c[i-1]; } for(int i=arr.length-1;i>0;i--){ arr_b[arr_c[arr[i]]] = arr[i]; arr_c[arr[i]]--; } for(int i=1;i<arr.length;i++){ arr[i]=arr_b[i]; } } }