常用排序算法

1.冒泡法

冒泡排序(Bubble Sort)
是一种较简单的排序算法。它会遍历若干次要排序的数列,每次遍历时,它都会从前往后依次的比较相邻两个数的大小;如果前者比后者大,则交换它们的位置。这样,一次遍历之后,最大的元素就在数列的末尾! 采用相同的方法再次遍历时,第二大的元素就被排列在最大元素之前。重复此操作,直到整个数列都有序为止!
冒泡法图解
在这里插入图片描述
代码演示

public class ArraySortDemo {
    public static void main(String[] args) {
      
        
        int[] arr = {24, 69, 80, 57, 13,1,4,6,-1};
       

        for (int j = 0; j <arr.length-1; j++) {
            for (int i = 0; i < arr.length - 1-j; i++) {
             
                if (arr[i] > arr[i + 1]) {
                    int t = arr[i];
                    arr[i] = arr[i + 1];
                    arr[i + 1] = t;
                }

            }
        }
        }

2.选择排序

选择排序
遍历一遍,找到整个数组中最小的数,与位置0的数交换位置。
从1位置开始,继续遍历,找到最小的数,与1位置交换。以此类推。
选择排序图解
在这里插入图片描述
代码演示

public class ArraySortDemo2 {
    public static void main(String[] args) {
       
        int[] arr = {24, 69, 80, 57, 13, 4, 6, 90, -1};
 
        for (int index = 0; index < arr.length - 1; index++) {
            for (int i = 1 + index; i < arr.length; i++) {
                if (arr[index] > arr[i]) {
                    swapValue(arr, index, i);
                }
            }
        }
        System.out.println(Arrays.toString(arr));
    }
     private static void swapValue(int[] arr, int j, int i) {
        int t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }
}

3.直接插入排序

直接插入排序
从1位置开始,比较与前面数的大小,如果小于前面的数,则交换位置,直到不再小于停止。
接着从2位置开始,重复这个过程。直到最后位置为止。

代码演示

public class ArrayDemo {
    public static void main(String[] args) {
    
        int[] arr = {2, 1, 0, 6, 9, 0, 10, 100, 20, 10, -1, 3, 6, 100, 200, 150};
      
        for (int i = 1; i < arr.length; i++) {
            for (int j = i; j > 0; j--) {
                if (arr[j] < arr[j - 1]) {
                    swapValue(arr, j, j - 1);
                }
            }
        }
        System.out.println(Arrays.toString(arr));
    }


    
    private static void swapValue(int[] arr, int j, int i) {
        int t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }
    }

4.希尔排序

希尔排序
希尔排序,是对直接插入排序的一种改进,他的思想选择一个合适的增量,然后经过一轮插入排序后,就会让数组大致有序
然后不断的缩小增量,进行插入排序,直到增量为1 整个排序结束。
代码演示

public static void ShellSort(this int[] arry)
         {
              int length = arry.Length;
             for (int h = length / 2; h > 0; h = h / 2)
              {
               
                 for (int i = h; i < length; i++)
                 {
                     int temp = arry[i];
                    if (temp < arry[i - h])
                     {
                        for (int j = 0; j < i; j += h)
                         {
                             if (temp<arry[j])
                            {
                                 temp = arry[j];
                                 arry[j] = arry[i];
                                 arry[i] = temp;
                            }
                         }
                     }
                 }
             }
         }

5.归并排序

归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
图解
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
代码演示

public class ArrayDemo3 {
    public static void main(String[] args) {

  int[] arr = {2, 10, 1, 0, 100, 3, 5, -1, 200, 109, 30, 1009, 109, 109, -100};
  chaiFen(arr, 0, arr.length - 1);
 System.out.println(Arrays.toString(arr));
  }

    private static void chaiFen(int[] arr, int startIndex, int endIndex) {
        //计算中间索引
        int centerIndex = (startIndex + endIndex) / 2;
        //递归来拆
        if (startIndex < endIndex) {
            //拆分左边
            chaiFen(arr, startIndex, centerIndex);
            //拆分右边
            chaiFen(arr, centerIndex + 1, endIndex);
            //归并
            mergerSort(arr, startIndex, centerIndex, endIndex);
        }
    }


 
    private static void mergerSort(int[] arr, int startIndex, int centerIndex, int endIndex) {
        //定义一个临时数组
        int[] tempArray = new int[endIndex - startIndex + 1];
        //定义临时数组的起始索引
        int index = 0;
        //定义左边数组的起始索引
        int i = startIndex;
        //定义右边数组的起始索引
        int j = centerIndex + 1;
        //循环比较左右两边数组的元素,往临时数组里面方法
        while (i <= centerIndex && j <= endIndex) {
            //进来比较
            if (arr[i] <= arr[j]) {
                tempArray[index] = arr[i];
                i++; //记得递增索引
            } else {
                tempArray[index] = arr[j];
                j++;//记得递增索引
            }

            index++; //临时数组的索引

        }

        //处理左边剩余元素

        while (i <= centerIndex) {
            tempArray[index] = arr[i];
            i++; //记得递增索引
            index++;
        }

        //处理右边剩余元素


        while (j <= endIndex) {
            tempArray[index] = arr[j];
            j++; //记得递增索引
            index++;
        }

        //这个时候我们的临时数组里面的元素已经排序好了

        //  System.out.println(Arrays.toString(tempArray));
        //遍历临时数组,将临时数组中的元素,放到原数组里面去
        for (int k = 0; k < tempArray.length; k++) {
            arr[k + startIndex] = tempArray[k];
        }


    }
}

6.快速排序

分治法:比大小,再分区
从数组中取出一个数,作为基准数。
分区:将比这个数大或等于的数全放到他的右边,小于他的数全放到他的左边。
再对左右区间重复第二步,直到各区间只有一个数。
代码演示

public class MyTest {
    public static void main(String[] args) {
        int[] arr = {2, 1, 0, 6, 9, 0, 10, 100, 20, 10, -1, 3, 6, 100, 200, 150};
        QuickSortUtils.quickSort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
}


public class QuickSortUtils {

    private QuickSortUtils() {
    }


    public static void quickSort(int[] arr,int startIndex,int endIndex){
        if(startIndex<endIndex){
            //找到基准数的索引
            int index=getIndex(arr,startIndex,endIndex);
            //对左右两边进行递归调用

            quickSort(arr,startIndex,index);
            quickSort(arr,index+1,endIndex);

        }
    }

 


    private static int getIndex(int[] arr, int startIndex, int endIndex) {
        //定义三个变量
        int i=startIndex;
        int j=endIndex;
        //定义基准数
        int x=arr[i];
        while (i<j){
         
            while (i<j&&arr[j]>=x){
                j--;

            }
        
            if(i<j){
                arr[i]=arr[j];
                i++;//顺便让i增一下
            }
         
            while (i<j&&arr[i]<x){

                i++;
            }

        
                arr[j] = arr[i];
                j--; //顺便让j减一下
            }


        }
    
        arr[i]=x;

        return i;
    }
}

7.基数排序

基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog®m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。
代码演示

  public static void radixSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        radixSort(arr, 0, arr.length - 1, maxbits(arr));
    }

    public static int maxbits(int[] arr) {
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < arr.length; i++) {
            max = Math.max(max, arr[i]);
        }
        int res = 0;
        while (max != 0) {
            res++;
            max /= 10;
        }
        return res;
    }

    public static void radixSort(int[] arr, int begin, int end, int digit) {
        final int radix = 10;
        int i = 0, j = 0;
        int[] count = new int[radix];
        int[] bucket = new int[end - begin + 1];
        for (int d = 1; d <= digit; d++) {
            for (i = 0; i < radix; i++) {
                count[i] = 0;
            }
            for (i = begin; i <= end; i++) {
                j = getDigit(arr[i], d);
                count[j]++;
            }
            for (i = 1; i < radix; i++) {
                count[i] = count[i] + count[i - 1];
            }
            for (i = end; i >= begin; i--) {
                j = getDigit(arr[i], d);
                bucket[count[j] - 1] = arr[i];
                count[j]--;
            }
            for (i = begin, j = 0; i <= end; i++, j++) {
                arr[i] = bucket[j];
            }
        }
    }

    public static int getDigit(int x, int d) {
        return ((x / ((int) Math.pow(10, d - 1))) % 10);
    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值