本文主要通过java代码实现java中相关高级的排序算法
1 快速排序
package com.sort.advance; /** * Created by jack on 2018/3/25. * 快速排序 * 算法时间复杂度 * 最好:T(n)= O(nlogn) * 最坏:T(n)= O(n*n):n次比较和n次移动 * * 算法流程: * 在数组中选择一个称为主元(pivot)的元素,将数组分为两部分,使得 第一部分中的所有元素都小于或等于主元,而第二部分的所有元素都大于主元 * 对第一部分递归地应用快速排序算法,然后对第二部分递归地应用快速排序算法 * * 算法策略: * 二分法+递归 */ public class QuickSort { /** * * @param arr 原始数组 * @param left 从第一个元素开始 * @param right 从最后一个元素开始 * @param point 数组中第一个元素的值 * @return */ public static int partition(long arr[],int left, int right,long point) { int leftPtr = left - 1; int rightPtr = right; while(true) { //循环,将比关键字小的留在左端 while(leftPtr < rightPtr && arr[++leftPtr] < point); //循环,将比关键字大的留在右端 while(rightPtr > leftPtr && arr[--rightPtr] > point); if(leftPtr >= rightPtr) { break; } else { long tmp = arr[leftPtr]; arr[leftPtr] = arr[rightPtr]; arr[rightPtr] = tmp; } } //将关键字和当前leftPtr所指的这一个进行交换 long tmp = arr[leftPtr]; arr[leftPtr] = arr[right]; arr[right] = tmp; return leftPtr; } public static void displayArr(long[] arr) { System.out.print("["); for(long num : arr) { System.out.print(num + " "); } System.out.print("]"); System.out.println(); } /** * * @param arr 原始数组 * @param left 从第一个元素开始 * @param right 从最后一个元素开始 */ public static void sort(long[] arr, int left, int right) { if(right - left <= 0) { return; } else { //设置关键字 默认是数组最后一个元素 long point = arr[right]; //获得切入点,同时对数组进行划分 int partition = partition(arr, left, right, point); //System.out.println("partition:"+partition); //对左边的子数组进行快速排序 sort(arr,left,partition - 1); //对右边的子数组进行快速排序 sort(arr,partition + 1, right); } } public static void main(String[] args) { long[] arr ={1,3,2,4,5,7,6,10,9}; QuickSort.displayArr(arr); QuickSort.sort(arr, 0, arr.length - 1); QuickSort.displayArr(arr); } }
2 归并排序
package com.sort.advance; import java.util.Arrays; /** * Created by jack on 2018/3/24. * 归并排序:都有有序的序列列表合并成一个新的 * * 算法本质:递归排序+合拼 * * 算法流程 * 把待排序序列分为若干个子序列,每个子序列是有序的 * 然后再把有序子序列合并为整体有序序列 * * 算法复杂度:O(nlogn) */ public class MergeSort { /** * 多个有序列表归并一个整的有序列表 * @param nums * @param low * @param mid * @param high */ public static void merge(int[] nums, int low, int mid, int high) { int[] temp = new int[high - low + 1]; int i = low;// 左指针 int j = mid + 1;// 右指针 int k = 0; // 把较小的数先移到新数组中 while (i <= mid && j <= high) { if (nums[i] < nums[j]) { temp[k++] = nums[i++]; } else { temp[k++] = nums[j++]; } } // 把左边剩余的数移入数组 while (i <= mid) { temp[k++] = nums[i++]; } // 把右边边剩余的数移入数组 while (j <= high) { temp[k++] = nums[j++]; } // 把新数组中的数覆盖nums数组 for (int k2 = 0; k2 < temp.length; k2++) { nums[k2 + low] = temp[k2]; } } /** * 排序 * @param nums * @param low * @param high * @return */ public static int[] sort(int[] nums, int low, int high) { int mid = (low + high) / 2; if (low < high) { // 左边 sort(nums, low, mid); // 右边 sort(nums, mid + 1, high); // 左右归并 merge(nums, low, mid, high); } return nums; } public static void main(String[] args) { int[] nums = { 2, 7, 8, 3, 1, 6, 9, 0, 5, 4 }; MergeSort.sort(nums, 0, nums.length-1); System.out.println(Arrays.toString(nums)); } }
3 桶排序
package com.sort.advance; /** * Created by jack on 2018/3/24. * 桶排序 * 算法流程:桶的最大数量是大于数组中最大的元素的值+1 * * 算法本质:空间换时间 * 算法复杂度: * 线性的O(N+C),其中C=N*(logN-logM)。如果相对于同样的N,桶数量M越大,其效率越高,最好的时间复杂度达到O(N) */ @SuppressWarnings("all") public class BucketSort { /** * 桶排序 * * 参数说明: * a -- 待排序数组 * max -- 数组a中最大值的范围 */ public static void bucketSort(int[] a, int max) { int[] buckets; if (a==null || max<1) return ; // 创建一个容量为max的数组buckets,并且将buckets中的所有数据都初始化为0。 buckets = new int[max]; // 1. 计数 for(int i = 0; i < a.length; i++) buckets[a[i]]++; // 2. 排序 for (int i = 0, j = 0; i < max; i++) { while( (buckets[i]--) >0 ) { a[j++] = i; } } buckets = null; } public static void main(String[] args) { int i; int a[] = {8, 2, 31, 4, 32, 6, 63, 34, 9}; System.out.printf("before sort:"); for (i = 0; i < a.length; i++) System.out.printf("%d ", a[i]); System.out.printf("\n"); bucketSort(a, 64); // 桶排序 System.out.printf("after sort:"); for (i = 0; i < a.length; i++) System.out.printf("%d ", a[i]); System.out.printf("\n"); } }
4 堆排序
4.1 构建堆信息
package com.sort.advance.heap; /** * Created by jack on 2018/3/25. * 节点信息 */ public class HeapNode { private int idata; public HeapNode(int key){ idata = key; } public int getKey(){ return idata; } public void setKey(int id){ idata=id; } }
4.2 堆基本操作
package com.sort.advance.heap; /** * Created by jack on 2018/3/25. * 堆信息 */ @SuppressWarnings("all") public class Heap { private HeapNode[]heapArray;//存储堆的数组 private int maxSize;//数组最大长度 private int currentSize;//当前堆的大小 public Heap(int max){ maxSize = max; currentSize = 0; heapArray = new HeapNode[maxSize]; } /** * 堆是否为空 */ public boolean isEmpty(){ return currentSize==0; } /** * 新增元素 */ public boolean insert(int key){ if (currentSize==maxSize)return false;//堆已经满了 HeapNode newHeapNode = new HeapNode(key); heapArray[currentSize] = newHeapNode;//新节点放到数据最后位置 trickleUP(currentSize);//向上调整 currentSize++; return true; } /** * 新增元素-堆排序的 */ public void insertAt(int index,HeapNode heapNode){ heapArray[index]= heapNode; } public void incrementSize(){ currentSize++; } /** * 向上调整 从0开始 */ public void trickleUP(int index){ int parent=(index-1)/2; HeapNode bottom = heapArray[index]; // parent=0 代表已经是跟节点 不需要调整 //如果当前要移动的节点的值比父节点的大 那么就进行交换 while(index>0 && heapArray[parent].getKey()<bottom.getKey()){ heapArray[index]=heapArray[parent]; index = parent; parent = (parent-1)/2; } heapArray[index]=bottom; } /** * 向下调整 */ public void trickleDown(int index){ int largetChild; HeapNode top =heapArray[index]; while (index<currentSize/2){ int leftChild = 2*index+1; int rightChild = leftChild +1; if(rightChild<currentSize && heapArray[leftChild].getKey()<heapArray[rightChild].getKey()) largetChild = rightChild; else largetChild = leftChild; if (top.getKey()>=heapArray[largetChild].getKey())break; heapArray[index] = heapArray[largetChild]; index = largetChild; } heapArray[index]=top; } /** * 删除堆中元素-根元素 */ public HeapNode remove(){ HeapNode root = heapArray[0]; heapArray[0]=heapArray[--currentSize];//把最后一个数据项先移动到根节点 trickleDown(0);//把新的根位置的数据项进行比较向下调整 return root; } /** * 改变堆中的值 */ public boolean change(int index,int newvalue){ //无效位置 if (index<0 || index>=currentSize)return false; //获取老的值 int oldvalue = heapArray[index].getKey(); //设置新的值 heapArray[index].setKey(newvalue); //老的值比新的值小 向上调整 if(oldvalue<newvalue)trickleUP(index); else trickleDown(index);//向下调整 return true; } /** * 显示堆信息 */ public void displayHeap(){ System.out.print("heaparray:"); for (int m=0;m<currentSize;m++) if (heapArray[m]!= null) System.out.print(heapArray[m].getKey()+" "); else System.out.println("--"); System.out.println(); //以树状形式显示 int nBlanks=32; int itemsPerRow=1; int column=0; int j=0; String dots ="..................................."; System.out.println(dots+dots); while (currentSize>0){ if (column==0){ for (int k = 0; k <nBlanks ; k++) { System.out.print(' '); } } System.out.print(heapArray[j].getKey()); if (++j==currentSize)break; if (++column==itemsPerRow){ nBlanks/=2; itemsPerRow*=2; column=0; System.out.println(); } else{ for (int k = 0; k <nBlanks*2-2 ; k++) System.out.print(' '); } } System.out.println("\n"+dots+dots); } public void displayArray(){ for (int i=0;i<maxSize;i++){ System.out.print(heapArray[i].getKey()+" "); } System.out.println(); } }
4.3 堆测试
package com.sort.advance.heap; import java.io.*; /** * Created by jack on 2018/3/25. * 堆测试 */ public class HeapApp { public static String getString()throws IOException{ InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr); return br.readLine(); } public static char getChar()throws IOException{ return getString().charAt(0); } public static int getInt()throws IOException{ return Integer.parseInt(getString()); } public static void main(String[] args)throws IOException { int value,value2; Heap heap = new Heap(31); boolean success; heap.insert(70); heap.insert(40); heap.insert(50); heap.insert(20); heap.insert(60); heap.insert(100); heap.insert(80); heap.insert(30); heap.insert(10); heap.insert(90); while (true){ System.out.print("enter first letter of show,insert,remove,change:"); int choice =getChar(); switch (choice){ case 's': heap.displayHeap(); break; case 'i': System.out.print("enter value to insert"); value=getInt(); success=heap.insert(value); if (!success){ System.out.println("can not insert heap full"); break; } case 'r': if (!heap.isEmpty())heap.remove(); else System.out.println("heap is empty can not remove"); break; case 'c': System.out.print("enter current index of item:"); value=getInt(); System.out.print("enter new key:"); value2=getInt(); success=heap.change(value,value2); if (!success) System.out.println("invalid index"); break; default: System.out.println("invalid entry\n"); } } } }
4.4 堆排序
package com.sort.advance.heap; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** * Created by jack on 2018/3/25. * 堆排序 */ public class HeapAppSort { private static String getString()throws IOException { InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr); return br.readLine(); } private static int getInt()throws IOException{ return Integer.parseInt(getString()); } public static void main(String[] args)throws IOException { int size,j; System.out.print("enter number of items:"); size=getInt(); Heap heap = new Heap(size); for (j=0;j<size;j++){ int random = (int) (Math.random()*100); HeapNode newnode = new HeapNode(random); heap.insertAt(j,newnode); heap.incrementSize(); } System.out.print("随机添加元素到堆中:"); heap.displayArray(); for (j = size/2-1; j>=0; j--) { heap.trickleDown(j); } System.out.print("初始化一个最大堆:"); heap.displayArray(); for (j=size-1;j>=0;j--){ HeapNode heapNode = heap.remove(); heap.insertAt(j, heapNode); } System.out.print("对生成后的最大堆进行排序:"); heap.displayArray(); } }