大纲:
- 冒泡排序
- 选择排序
- 插入排序
- 希尔排序
- 快速排序
- 归并排序
- 基数排序
- 堆排序
一、冒泡排序
/** * 冒泡排序 * 依次比较相邻的两个值,将大的交换到这2个位置的后面一个位置,然后继续比较直到最后一个值则找出了最大的数。 * * @param arr */ private static void bubble(int[] arr) { for (int i = 0; i <= arr.length - 1; i++) { for (int j = 0; j <= arr.length - 2 - i; j++) { if (arr[j] > arr[j + 1]) { int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } }
二、选择排序
/** * 选择排序 * 遍历数组长度n个元素找到最大的,放到最后,再便利数组长度n-1个元素最大的,放到倒数第二个位置。 * * @param arr */ private static void selection(int[] arr) { int maxindex = 0; for (int i = 0; i <= arr.length - 1; i++) { for (int j = 0; j <= arr.length - 1 - i; j++) { if (arr[j] > arr[maxindex]) { maxindex = j; } } int temp = arr[arr.length - 1 - i]; arr[arr.length - 1 - i] = arr[maxindex]; arr[maxindex] = temp; } }
三、插入排序
/** * 插入排序 * 依次左侧n个数组有序,每次找到n+1因该插入的位置 * * @param arr */ private static void insertion(int[] arr) { for (int i = 1; i <= arr.length - 1; i++) { int temp = arr[i]; int index = i; while (index - 1 >= 0 && temp < arr[index - 1]) { arr[index] = arr[index - 1]; index--; } arr[index] = temp; } }
四、希尔排序
/** * 希尔排序 * 步长分别是arr.length开始,每次除以2 * 然后将arr分成gap个与步长相同的组,分别进行插入排序 * * @param arr */ private static void shell(int[] arr) { for (int gap = arr.length/2; gap >0; gap/=2) { for (int i = gap; i < arr.length; i++) { int temp = arr[i]; int index = i; while (index - gap >= 0 && arr[index - gap] > temp) { arr[index] = arr[index-gap]; index-=gap; } arr[index] = temp; } } }
五、快速排序
/** * 快速排序 * 将第一个数作为中轴,将比它大的放在它右边,比它小的都放在它左边 * 再递归两边的子数组 * * @param arr */ private static void qs(int[] arr) { quickSort(arr, 0, arr.length - 1); } private static void quickSort(int[] arr, int begin, int end) { if (end>begin) { int left = begin; int right = end; int temp = arr[left]; while (right > left) { while (right > left && arr[right] >= temp) { right--; } arr[left] = arr[right]; while (right > left && arr[left] <= temp) { left++; } arr[right] = arr[left]; } arr[right] = temp; quickSort(arr,begin,right-1); quickSort(arr,right+1,end); } }
六、归并排序
/** * 归并排序 * 分治思想,先将数组拆分至2个数,然后合并计算 * 合并过程:分成左右段用双指针,将小的一个放到临时数组中,再将左右没有放置到临时数组中的copy过去,最后复制回arr中 * @param arr */ private static void ms(int arr[]) { int[] temp = new int[arr.length]; mergeSort(arr,0,arr.length-1,temp); } private static void mergeSort(int[] arr, int begin, int end, int[] temp) { if (end>begin) { int mid= (begin+end)/2; mergeSort(arr,begin,mid,temp); mergeSort(arr,mid+1,end,temp); int left = begin; int right = mid+1; int index = 0; while (left <= mid && right <= end) { if (arr[left]<arr[right]) { temp[index++] = arr[left++]; }else{ temp[index++] = arr[right++]; } } while (left <= mid) { temp[index++] = arr[left++]; } while (right <= end) { temp[index++] = arr[right++]; } index = 0; while (begin <= end) { arr[begin++] = temp[index++]; } } }
七、基数排序
private static void radixSort(int arr[]){ //找到最大数取位数 int max = arr[0]; for (int i : arr) { if (i>max) { max = i; } } int maxLength = (""+max).length(); //按照依次按照个十百千万位放入对应的桶中再取出 int[][] bucket = new int[10][arr.length]; int[] bucketCount = new int[10]; int radix = 1; int index = 0; for (int i = 0; i < maxLength; i++) { for (int j : arr) { int base = j / radix % 10; bucket[base][bucketCount[base]++] = j; } for (int j = 0; j < 10; j++) { for (int k = 0; k < bucketCount[j]; k++) { arr[index++] = bucket[j][k]; } } radix*=10; index=0; bucketCount = new int[10]; } }
八、堆排序
private static void heapSort(int[] arr){ //从第一个非叶子结点,从下向上构建大顶堆 for (int i = (arr.length-1-1)/2; i >=0; i--) { heapAdjust(arr,i,arr.length); } //第一个元素和第i个对调,然后重新构造大顶堆 for (int i = arr.length-1; i >0 ; i--) { int temp = arr[0]; arr[0] = arr[i]; arr[i] = temp; heapAdjust(arr,0,i); } } private static void heapAdjust(int[] arr,int index,int length){ //这个就是插入排序思路,从下向上构建有序的大顶堆 int temp = arr[index]; //一个元素的左子节点时2n+1 for (int i = index*2+1; i <length ; i=i*2+1) { //比较左右节点,找出较大子节点进行对比 if (i+1<length&&arr[i]<arr[i+1]) { i++; } //子节点比当前节点大 if (temp>=arr[i]) { break; //子节点比当前节点小,当前节点被子节点覆盖,指针下移 }else { arr[index] = arr[i]; index = i; } } arr[index] = temp; }