排序算法
笔者埋坑后面再来分析总结
1. 插入排序
直接插入排序:O(n^2)
public static int[] insertSort(int[] arr){ int i,j,temp; for(i = 1; i < arr.length; i++){ temp = arr[i]; for(j = i; j > 0 && arr[j-1] > temp; j--){ arr[j] = arr[j-1]; } arr[j] = temp; } return arr; }
二分插入排序:O(n^2)
public static int[] binaryInsertSort(int[] arr){ int i,j,low,high,mid,temp; for(i = 1; i < arr.length; i++){ temp = arr[i]; low = 0; high = i - 1; while(low <= high){ //最后一个也要比较,比完就知道具体位置了 mid = (low + high) / 2; if(temp < arr[mid]){ high = mid - 1; }else{ low = mid + 1; } } for(j = i; j > high+1; j--){ arr[j] = arr[j-1]; } arr[high+1] = temp; } return arr; }
希尔排序:O(nlog n)
public static int[] shellSort(int[] arr){ int i,j,d,temp; for(d = arr.length/2; d > 0; d /= 2){ for(i = d; i < arr.length; i++){ temp = arr[i]; for(j = i; j > 0 && arr[j-d] > temp; j -=d){ arr[j] = arr[j-d]; } arr[j] = temp; } } return arr; }
2. 交换排序
冒泡排序:O(n^2)
public static int[] bubbleSort(int[] arr){ int i,j,temp; for(i = 0; i < arr.length - 1; i++){ for(j = 0; j < arr.length - 1 - i; j++){ if(arr[j] > arr[j+1]){ temp = arr[i+1]; arr[i+1] = arr[i]; arr[i] = temp; } } } return arr; }
快速排序:O(nlog2 n)
public static int partition(int[] arr,int i,int j){ int temp = arr[i]; //基准 while(i < j){ while(i < j && temp <= arr[j]){ j--; } arr[i] = arr[j]; while(i < j && arr[i] < temp ){ i++; } arr[j] = arr[i]; } arr[i] = temp; return i; } public static void quickSort(int[] arr,int i,int j){ int mid; if(i < j){ mid = partition(arr,i,j); quickSort(arr, i, mid-1); quickSort(arr, mid+1, j); } }
3. 选择排序
简单选择排序:O(n^2)
public static void SimpleSelectSort(int[] arr){ int i,j,index,temp; for(i = 0; i < arr.length-1; i++){ index = i; for(j = i+1; j < arr.length; j++){ if(arr[index] > arr[j]){ index = j; } } temp = arr[index]; arr[index] = arr[i]; arr[i] = temp; } }
堆排序:O(nlog2 n)
public static void sift(int[] arr,int low,int high){ int i = low; //父结点 int j = i * 2; //左子结点 int temp = arr[i]; //临时保存根结点 while(j <= high){ if(j < high && arr[j] < arr[j+1]){ j++; //指向右子结点 } if(temp < arr[j]){ arr[i] = arr[j]; //较大子节点放入根节点 i = j; j = i * 2; }else{ break; //默认左右子树是大根堆,若不用交换,当前结点的下面都是大根堆 } } arr[i] = temp; //最后筛选完成才将根节点与最后交换的结点互换 } public static void heapSort(int[] arr){ //建立初始堆 int i,temp; int length = arr.length-1; for(i = length/2; i >= 0; i--){ sift(arr,i,length); } // 走 n-1躺 for(i = length; i >= 1; i--){ temp = arr[i]; arr[i] = arr[0]; arr[0] = temp; //交换arr[1],arr[i] sift(arr,0,i-1); } }
4. 归并排序
二路查找:O(nlog2 n)
public static void merge(int[] arr,int left,int mid,int right){ int[] leftArr = new int[mid - left]; int[] rightArr = new int[right - mid + 1]; for(int i = left; i < mid; i++){ leftArr[i - left] = arr[i]; } for(int i = mid; i <= right; i++){ rightArr[i - mid] = arr[i]; } int i = 0, j = 0; int index = left; while(i < leftArr.length && j < rightArr.length){ if(leftArr[i] < rightArr[j]){ arr[index] = leftArr[i]; i++; index++; }else{ arr[index] = rightArr[j]; j++; index++; } } while(i < leftArr.length){ arr[index] = leftArr[i]; i++; index++; } while(j < rightArr.length){ arr[index] = rightArr[j]; j++; index++; } } public static void mergeSort(int[] arr, int left, int right){ if(left < right){ int mid = (left + right) / 2; mergeSort(arr, left, mid); mergeSort(arr, mid+1, right); merge(arr, left, mid+1, right); } }
5. 基数排序(桶排序,非计数排序)
// 返回最大值 private static int findMax(int[] arr){ int temp = arr[0]; for(int value : arr){ if(temp < value){ temp = value; } } return temp; } public static void radixSort(int[] arr){ int max = findMax(arr); // 比较次数由最大值的位数决定 for(int i = 1; max / i > 0; i *= 10){ int[][] buckets = new int[arr.length][10]; // 将每一个值根据当前比较的位数放入桶中 for(int j = 0; j < arr.length; j++){ int num = (arr[j] / i) % 10; buckets[j][num] = arr[j]; } int k = 0; for(int m = 0; m < 10; m++){ for(int n = 0; n < arr.length; n++){ if(buckets[n][m] != 0){ arr[k++] = buckets[n][m]; } } } } }
相关推荐
randy0 2020-11-17
lixiaotao 2020-10-07
美丽的泡沫 2020-09-08
nongfusanquan0 2020-08-18
hang0 2020-08-16
earthhouge 2020-08-15
算法改变人生 2020-07-28
troysps 2020-07-19
Broadview 2020-07-19
chenfei0 2020-07-18
风吹夏天 2020-07-07
yangjingdong00 2020-07-05
数据与算法之美 2020-07-05
shawsun 2020-07-04
数据与算法之美 2020-07-04
要知道时间复杂度只是描述一个增长趋势,复杂度为O的排序算法执行时间不一定比复杂度为O长,因为在计算O时省略了系数、常数、低阶。实际上,在对小规模数据进行排序时,n2的值实际比 knlogn+c还要小。
Evankaka 2020-07-04
田有朋 2020-06-28