数据结构的八大排序算法

- 两个星期重新学习了排序算法,包括:
- 冒泡排序
Bubble1 class Bubble { 2 //80000个数据测试结果 9秒 3 public static int[] BubbleSort(int[] arr) { 4 int temp = 0; 5 //外层for循环确定从头开始比较的趟数 6 for (int i = 0; i < arr.length - 1; i++) { 7 //j是从头开始遍历,然后每一次遍历完后,都会确定一个最大数,因此需要在length-1的基础上在 -i 8 for (int j = 0; j < arr.length - 1 - i; j++) { 9 //如果前一个比后一个就交换位置 10 if (arr[j] > arr[j + 1]) { 11 temp = arr[j]; 12 arr[j] = arr[j + 1]; 13 arr[j + 1] = temp; 14 } 15 } 16 } 17 return arr; 18 } 19 }
- 插入排序
Insert1 class Insert { 2 public static int[] InsertSort(int[] arr) { 3 //插入排序,按顺序每一趟都会将对应增长的index处的数据插入有序数组;从小到大 4 //长度为n的数组,从index 1 -- n-1 插入n-1次 5 for (int i = 1; i < arr.length; i++) { 6 //将arr[i]与前i-1个数据 逆序 比较,一旦遇到比它小的就插到它的后面,如若没有就插到第0个位置 7 //待插入的值 8 int insertVal = arr[i]; 9 //前面排好序的数组的最后一位下标 10 int insertIndex = i - 1; 11 12 //insertIndex>= 0 保证不越界 13 //insertVal < arr[insertIndex] 还没有找到插入位置 14 while (insertIndex >= 0 && insertVal < arr[insertIndex]) { 15 arr[insertIndex + 1] = arr[insertIndex]; 16 insertIndex--; 17 } 18 19 //优化 20 if (insertIndex + 1 != i) { 21 //跳出循环后即可得到插入位置i 22 arr[insertIndex + 1] = insertVal; 23 } 24 25 } 26 return arr; 27 } 28 }
- 选择排序
Select1 class Select { 2 public static int[] SelectSort(int[] arr) { 3 //每次确定最小数的位置,和未排序的数组首交换位置 4 for (int i = 0; i < arr.length - 1; i++) { 5 int index = i; 6 for (int j = i + 1; j < arr.length; j++) { 7 if (arr[index] > arr[j]) { 8 index = j; 9 } 10 } 11 //如果index不是第一个遍历的数,就互换; 12 if (index != i) { 13 int temp = arr[index]; 14 arr[index] = arr[i]; 15 arr[i] = temp; 16 } 17 18 } 19 return arr; 20 } 21 }
- 快速排序
Quick1 //快速排序 2 class Quick { 3 public static void QuickSort(int[] arr, int left, int right) { 4 if (left < right) { 5 //枢轴 6 int pivot = arr[left]; 7 int l = left; 8 int r = right; 9 //这里有个很重要的地方,为什么先排右侧的数且可以直接赋值给arr[l],因为我是选择的left作为枢,它的值已经被存起来的,所以在位置可以直接被覆盖 10 while (l < r) { 11 //右侧中,找到比枢小的数就放在其左侧 12 while (l < r && arr[r] >= pivot) { 13 r--; 14 } 15 //跳出这个循环,r指向一个小于pivot的数 16 if (l != r) { 17 arr[l] = arr[r]; 18 } 19 20 //左侧中,找到比枢大的数放在右侧 21 while (l < r && arr[l] <= pivot) { 22 l++; 23 } 24 //跳出这个循环,l指向一个大于pivot的数 25 if (l != r) { 26 arr[r] = arr[l]; 27 } 28 29 30 } 31 32 //枢到指定位置 33 arr[l] = pivot; 34 35 36 //跳出循环后,对枢轴前面的数 和 后面的数 分别进行判断 37 QuickSort(arr, left, l - 1); 38 QuickSort(arr, r + 1, right); 39 40 } 41 } 42 }
- 希尔排序
Shell1 //希尔排序 2 class Shell { 3 public static int[] ShellSort(int[] arr) { 4 //移位法 5 int gap = arr.length / 2; 6 while (gap > 0) { 7 //执行同一个步长下的数的排序 8 for (int i = gap; i < arr.length; i++) { 9 int j = i; 10 int temp = arr[j]; 11 //如果当前数,比同一组的前一个数小,就有必要进行移位操作; 12 if (arr[j] < arr[j - gap]) { 13 while (j - gap >= 0 && temp < arr[j - gap]) { 14 //后移,把j的位置让给前一个gap,空出来的就是j-gap赋值给j 15 arr[j] = arr[j - gap]; 16 j -= gap; 17 } 18 //跳出循环就是j为空值; 19 arr[j] = temp; 20 } 21 22 } 23 gap /= 2; 24 } 25 26 return arr; 27 } 28 29 30 }
- 归并排序
Merge1 class Merge { 2 //拆分+合并 3 public static void MergeSort(int[] arr, int left, int right, int[] temp) { 4 if (left < right) { 5 int mid = (left + right) / 2; 6 //拆分 7 MergeSort(arr, left, mid, temp); 8 MergeSort(arr, mid + 1, right, temp); 9 //合并 10 Merge(arr, left, mid, right, temp); 11 } 12 } 13 14 /** 15 * 把从left到right的以mid为分界的两个数组排序 16 * 17 * @param arr 原数组 18 * @param left 左下标 19 * @param right 右下标 20 * @param mid 中值 21 * @param temp 存储中间结果 22 */ 23 public static void Merge(int[] arr, int left, int mid, int right, int[] temp) { 24 //System.out.println("left= "+left+" mid="+mid+" right="+right); 25 int l = left; 26 int j = mid + 1; 27 int t = 0; 28 //将左边和右边的有序数组进行传输 29 while (l <= mid && j <= right) { 30 if (arr[l] <= arr[j]) { 31 temp[t] = arr[l]; 32 t++; 33 l++; 34 } else { 35 temp[t] = arr[j]; 36 t++; 37 j++; 38 } 39 } 40 //弹出这个循环后,可能左边或者右边的数组剩余 41 //左边有剩余 42 43 while (l <= mid) { 44 temp[t] = arr[l]; 45 t++; 46 l++; 47 } 48 49 //右边有剩余 50 51 while (j <= right) { 52 temp[t] = arr[j]; 53 t++; 54 j++; 55 } 56 57 58 //此时temp里面是left->right的有序数组,赋值给arr 59 //int leftTemp = left; 60 t = 0; 61 while (left <= right) { 62 arr[left] = temp[t]; 63 left++; 64 t++; 65 } 66 67 } 68 }
- 基数排序
Radix1 //基数排序 2 class Radix { 3 public static void radixSort(int[] arr) { 4 //首先要确定做多少次排序 5 int max = arr[0]; 6 for (int i = 1; i < arr.length; i++) { 7 if (max < arr[i]) { 8 max = arr[i]; 9 } 10 } 11 int times = (max + "").length(); 12 13 //创建二维数组,作为桶来存储数据 14 int[][] bucket = new int[10][arr.length]; 15 //创建一个数组,来存储每个桶有多少数据,方便取出 16 int[] bucketNum = new int[10]; 17 18 for (int i = 0, n = 1; i < times; i++, n *= 10) { 19 //将同位下各个数放入桶 20 for (int numIndex = 0; numIndex < arr.length; numIndex++) { 21 //每一个数末位 22 int lastNum = arr[numIndex] / n % 10; 23 //存入桶 24 bucket[lastNum][bucketNum[lastNum]] = arr[numIndex]; 25 bucketNum[lastNum]++; 26 } 27 28 //原数组下标 29 int t = 0; 30 //从桶中取出并放入arr 31 for (int outIndex = 0; outIndex < 10; outIndex++) { 32 //判断当前桶是否有数据 33 if (bucketNum[outIndex] != 0) { 34 //有数据 35 for (int o = 0; o < bucketNum[outIndex]; o++) { 36 arr[t] = bucket[outIndex][o]; 37 t++; 38 } 39 //桶中的数据一定要记得清零 40 bucketNum[outIndex] = 0; 41 } 42 43 } 44 } 45 } 46 }
- 堆排序
Heap1 //堆排序 2 class Heap { 3 public static void heapSort(int[] arr){ 4 //将数组调整为大顶堆 5 for (int i= arr.length/2-1;i>=0;i--){ 6 adjustHeap(arr,i,arr.length); 7 } 8 int temp = 0; 9 //调整完毕后,交换堆顶元素与末尾元素 10 for (int j=arr.length-1;j>0;j--){ 11 temp = arr[j]; 12 arr[j] = arr[0]; 13 arr[0] = temp; 14 //最后一位已经是最大了,不必参与调整 15 adjustHeap(arr,0,j); 16 } 17 //System.out.println(Arrays.toString(arr)); 18 } 19 //调整为大顶堆 20 public static void adjustHeap(int[] arr, int i, int length) { 21 //取出当前节点值保存 22 int temp = arr[i]; 23 for (int k = 2 * i + 1; k < length; k = k * 2 + 1) { 24 //比较其子节点的大小 25 //如果右子节点比左子节点大,则k指向右子节点 26 if (k + 1 < length && arr[k] < arr[k + 1]) { 27 k++; 28 } 29 //比较父节点与较大子节点的大小关系 30 if (temp < arr[k]) { 31 //把子节点的值赋值给父节点 32 arr[i] = arr[k]; 33 //同时这个父节点为了便于接下来的子节点继续和它进行比较,把k值赋值给了i 34 i = k; 35 }else{ 36 break; 37 } 38 } 39 arr[i] = temp; 40 41 } 42 }
- 冒泡排序
- 学习这些算法的过程中,不仅是对这些年代久远但是设计极其巧妙的算法充满了惊叹,更是对于这些基础充满了敬意,难怪bat动不动要手撕一个快拍,如果你不理解他的思想,就不可能写出如此巧妙的算法,没什么好说的,这些排序算法是真的牛x !每次学都受益匪浅!
- 现在是2020-7-24,秋招也开始了,我的准备却是远远不够的。LeetCode的题打算刷简单和中等这两个难度,然后将Java的多线程、IO流深刻一下,过一遍计网、操作系统就投简历了。不能贪多,面试的准备永远是不够的,先步步为营,加油!!!

浙公网安备 33010602011771号