数据结构的八大排序算法

 

 

  1.  两个星期重新学习了排序算法,包括:
    • 冒泡排序
       1 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 }
      Bubble
    • 插入排序
       1 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 }
      Insert
    • 选择排序
       1 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 }
      Select
    • 快速排序
       1 //快速排序
       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 }
      Quick
    • 希尔排序
       1 //希尔排序                                                            
       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 }                                                                 
      Shell
    • 归并排序
       1 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 }
      Merge
    • 基数排序
       1 //基数排序
       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 }
      Radix
    • 堆排序
       1 //堆排序
       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 }
      Heap
  2. 学习这些算法的过程中,不仅是对这些年代久远但是设计极其巧妙的算法充满了惊叹,更是对于这些基础充满了敬意,难怪bat动不动要手撕一个快拍,如果你不理解他的思想,就不可能写出如此巧妙的算法,没什么好说的,这些排序算法是真的牛x !每次学都受益匪浅!
  3. 现在是2020-7-24,秋招也开始了,我的准备却是远远不够的。LeetCode的题打算刷简单和中等这两个难度,然后将Java的多线程、IO流深刻一下,过一遍计网、操作系统就投简历了。不能贪多,面试的准备永远是不够的,先步步为营,加油!!!
posted @ 2020-07-24 17:08  -忘情冷雨夜-  阅读(177)  评论(0)    收藏  举报