排序算法

前言

排序算法有很多,这里只列举了常见的几种基础算法如:冒泡排序、插入排序、选择排序、快速排序。对算法感兴趣的可以去LeeCode里面深度学习哦。

冒泡排序

private static void Swap(int[] nums,int i,int j){
         int val=nums[i];
         nums[i]=nums[j];
         nums[j]=val;
}
/*
     冒泡排序:
        1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
        2.对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
        3.针对所有的元素重复以上的步骤,除了最后一个。
        4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
     */
     public static void  BubbleSort(int[] nums){
         for(int i=nums.length-1;i>0;i--){   //外层循环控制排序的轮数
             boolean isSorted=true;
             for(int j=0;j<i;j++){        //内层循环每次将未排序序列中最大的数冒泡到最后端
                 if(nums[j]>nums[j+1]){
                     Swap(nums,j,j+1);
                     isSorted=false;
                 }
             }
             if(isSorted) break;
         }
     }     

选择排序

private static void Swap(int[] nums,int i,int j){
         int val=nums[i];
         nums[i]=nums[j];
         nums[j]=val;
     }
     /*
     选择排序:
        1.第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置
        2.然后再从剩余的未排序元素中寻找到最小(大)元素,放到已排序的序列的末尾
        3.以此类推,直到全部待排序的数据元素的个数为零
      */
     public static void SelectSort(int[] nums){
         for(int i=0;i<nums.length;i++){
             int index=i;
             for(int j=i+1;j<nums.length;j++){
                 if(nums[j]<nums[index]) index=j;
             }
             Swap(nums,i,index);
         }
     }

插入排序

/*
插入排序:
  基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。
  在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,
  内层循环对当前元素前面有序表进行待插入位置查找,并进行移动
*/
public static void InsertSort(int[] nums){
   for(int i=1;i<nums.length;i++){
       int val=nums[i];
       int j=i;
       while(j>0&&nums[j-1]>val){
           nums[j]=nums[j-1];
           j--;
       }
       nums[j]=val;
   }
}

快速排序

private static void Swap(int[] nums,int i,int j){
         int val=nums[i];
         nums[i]=nums[j];
         nums[j]=val;
     }
      /*
     快速排序:
        1.首先设定一个分界值,通过该分界值将数组分成左右两部分。
        2.将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。
        3.然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
        4.重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
     */
     public static void FastSort(int[] nums,int start,int end) {
         if(start>=end) return ;
         int val=nums[start];
         int i=start,j=end;
         while (i<j){
             // 顺序很重要,先从右边开始往左找,直到找到比base值小的数
              while(nums[j] >= val && i < j) {
                      j--;
                  }
              // 再从左往右边找,直到找到比base值大的数
              while(nums[i] <= val && i < j) {
                      i++;
                  }
             if(i<j&&nums[i]>nums[j]){
                 Swap(nums,i,j);
             }
         }
         nums[start]=nums[i];
         nums[i]=val;
         FastSort(nums,start,i-1);
         FastSort(nums,i+1,end);
     }

总结

这里贴上部分排序时间复杂度:

在贴上所有代码

public class SortMethod {
    private static void Swap(int[] nums, int i, int j) {
        int val = nums[i];
        nums[i] = nums[j];
        nums[j] = val;
    }

    /*
    选择排序:
       1.第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置
       2.然后再从剩余的未排序元素中寻找到最小(大)元素,放到已排序的序列的末尾
       3.以此类推,直到全部待排序的数据元素的个数为零
     */
    public static void SelectSort(int[] nums) {
        for (int i = 0; i < nums.length; i++) {
            int index = i;
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[j] < nums[index]) index = j;
            }
            Swap(nums, i, index);
        }
    }

    /*
    冒泡排序:
       1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
       2.对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
       3.针对所有的元素重复以上的步骤,除了最后一个。
       4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
    */
    public static void BubbleSort(int[] nums) {
        for (int i = nums.length - 1; i > 0; i--) {   //外层循环控制排序的轮数
            boolean isSorted = true;
            for (int j = 0; j < i; j++) {        //内层循环每次将未排序序列中最大的数冒泡到最后端
                if (nums[j] > nums[j + 1]) {
                    Swap(nums, j, j + 1);
                    isSorted = false;
                }
            }
            if (isSorted) break;
        }
    }

    /*
    插入排序:
       基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。
       在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,
       内层循环对当前元素前面有序表进行待插入位置查找,并进行移动
    */
    public static void InsertSort(int[] nums) {
        for (int i = 1; i < nums.length; i++) {
            int val = nums[i];
            int j = i;
            while (j > 0 && nums[j - 1] > val) {
                nums[j] = nums[j - 1];
                j--;
            }
            nums[j] = val;
        }
    }

    /*
    快速排序:
       1.首先设定一个分界值,通过该分界值将数组分成左右两部分。
       2.将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。
       3.然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
       4.重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
    */
    public static void FastSort(int[] nums, int start, int end) {
        if (start >= end) return;
        int val = nums[start];
        int i = start, j = end;
        while (i < j) {
            // 顺序很重要,先从右边开始往左找,直到找到比base值小的数
            while (nums[j] >= val && i < j) {
                j--;
            }
            // 再从左往右边找,直到找到比base值大的数
            while (nums[i] <= val && i < j) {
                i++;
            }
            if (i < j && nums[i] > nums[j]) {
                Swap(nums, i, j);
            }
        }
        nums[start] = nums[i];
        nums[i] = val;
        FastSort(nums, start, i - 1);
        FastSort(nums, i + 1, end);
    }

}
Last Updated: