Java中的几种数组排序

Java中的排序

冒泡排序

原理:从一个数开始,依次往后比较,如果前面的数字比后面的大就交换,否则不交换,类似烧开水,水壶底的水泡往上冒。
图解分析:

现以数组[24,69,80,57,13]为例
在这里插入图片描述

代码实现

public class MyTest2 {
    public static void main(String[] args) {
        int[] arr={24,69,80,57,13};
        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;
                }
            }
        }
        System.out.println(Arrays.toString(arr));
    }
}

选择排序

原理:每一趟从待排序的数据元素选择最小的,存放到排序序列的起始位置,然后,再从剩余未排元素中继续寻找最小的,然后放到已排序的末尾,以此类推,直到所有元素均排完为止。

图解分析:
在这里插入图片描述

代码实现:

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

直接插入排序

原理:有一个待排序的数组array,数组长度为n。假设有有一个已经排好序的有序数组,用该数组对未排序的数组的元素,每一个元素都去与已经拍好的数组中的元素比较,然后有序的插入到有序的数组当中,直到将所有的待排序的记录全部插入为止。

例如:

•49,38,65,97,76,13,27 原始数据

•[49],38,65,97,76,13,27 从1索引开始插入

•[38,49], ,65,97,76,13,27

•[38,49,65] 97,76,13,27

•[38,49,65,97] 76,13,27

•[38,49,65,76,97]13,27

•[13,27,38,49,65,76,97],27

•[13,27,38,49,65,76,97]

代码实现

public class MyTest2 {
    public static void main(String[] args) {
        int[] arr={49,38,65,97,76,13,27 };
        for (int i = 1; i < arr.length; i++) {
            for (int j=i;j>0;j--){
                if (arr[j]<arr[j-1]){
                    int t=arr[j];
                    arr[j]=arr[j-1];
                    arr[j-1]=t;
                }
            }
        }
        System.out.println(Arrays.toString(arr));
    }
}

希尔排序

原理:它是对直接插入排序的一种改进,对于一个待排序的数列,取一个小于数列长度的间隔数,所有这个间隔数上的元素分成一组,然后对各组内的元素进行直接插入排序,这一趟排序之后,每一组的元素都是有序的,然后减小间隔数,继续去比较,当间隔数为1时,整个数列是有序的。
图解分析:
在这里插入图片描述

增量的选择一般选数组长度的一半,但是这样不是最合理的,我们用Kunth序列进行希尔排序,a=3*d+1;

代码实现

public class MyTest2 {
    public static void main(String[] args) {
       int[] arr={46,55,13,42,17,94,05,70};
       int jiange=1;
       while (jiange<arr.length/3) {
           jiange = 3 * jiange + 1;//数组的最大间隔
       }
        for (int h = jiange; h>0;h=(h-1)/3 ) {
            for (int j = h; j < arr.length;j++) {
                for (int i=j;i>h-1;i=i-h){
                    if (arr[i]<arr[i-h]){
                        int t=arr[i];
                        arr[i]=arr[i-h];
                        arr[i-h]=t;
                    }
                }
            }
        }
        System.out.println(Arrays.toString(arr));
    }
}
输出结果:[5, 13, 17, 42, 46, 55, 70, 94]

归并排序

原理:归并排序是一种递归算法,不断将列表拆分为一半,如果列表为空或有一个项,则按定义进行排序。如果列表有多个项,我们分割列表,并递归调用两个半部分的合并排序。一旦对两半排序完成,获取两个较小的排序列表并将它们组合成单个排序的新列表的过程。
图解分析:
在这里插入图片描述
在这里插入图片描述
代码实现

public class MyTest2 {
    public static void main(String[] args) {
        int[] arr = {56, 93, 17, 77, 31, 44, 55, 20};
        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;
//        System.out.println(startindex);
//        System.out.println(endindex);
        if(startindex<endindex){
            chaifen(arr,startindex,centerindex);
            chaifen(arr,centerindex+1,endindex);
            mergeSort(arr,startindex,centerindex,endindex);
        }
    }

    private static void mergeSort(int[] arr, int startindex, int centerindex, int endindex) {
        int[] temoArray=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]){
                temoArray[index]=arr[i];
                i++;
            }else {
                temoArray[index]=arr[j];
                j++;
            }
            index++;
        }
        while (i<=centerindex){
            temoArray[index]=arr[i];
            i++;
            index++;
        }
        while (j<=endindex){
            temoArray[index]=arr[j];
            j++;
            index++;
        }
//        System.out.println(Arrays.toString(temoArray));
//        System.out.println(startindex);
        for (int k = 0; k < temoArray.length; k++) {
            arr[k+startindex]=temoArray[k];
        }
    }
}

快速排序

选择一个关键值作为基准值。比基准值小的都在左边序列(一般是无序的),比基准值大的都在右边(一般是无序的)。一般选择序列的第一个元素。

一次循环:从后往前比较,用基准值和最后一个值比较,如果比基准值小的交换位置,如果没有继续比较下一个,直到找到第一个比基准值小的值才交换。找到这个值之后,又从前往后开始比较,如果有比基准值大的,交换位置,如果没有继续比较下一个,直到找到第一个比基准值大的值才交换。直到从前往后的比较索引>从后往前比较的索引,结束第一次循环,此时,对于基准值来说,左右两边就是有序的了。
代码实现:

public class MyTest2 {
    public static void main(String[] args) {
        int[] arr = {56, 93, 17, 77, 31, 44, 55, 20};
        QuickSort1(arr, 0, arr.length - 1);
        System.out.println(Arrays.toString(arr));
    }

    private static void QuickSort1(int[] arr, int startindex, int endindex) {
        if (startindex < endindex) {
            int index = getIndex(arr, startindex, endindex);
            QuickSort1(arr, startindex, index - 1);
            QuickSort1(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++;
            }
            while (i < j && arr[i] <= x) {
                i++;
            }
            if (i < j) {
                arr[j] = arr[i];
                j--;
            }
        }
        arr[i]=x;
        return i;
    }
}

基数排序

原理:类似于桶式排序,我们需要给待排序记录准备10个桶,为什么是10个??因为一个数的任何一位上,其数字大小都位于0~9之间,因此采用10个桶,桶的编号分别为0,1,2,3,4…9,对应待排序记录中每个数相应位的数值,基数排序也是因此而得名。我们先根据待排序记录的每个数的个位来决定让其加入哪个桶中

如:待排序数组为

278 109 63 930 589 184 505 269 8 83

求取每个数的个位数,依次为:8 9 3 0 9 4 5 9 8 3

依照其个位数决定将其加入哪个桶中

[0]930
[1]
[2]
[3]6383
[4]184
[5]505
[6]
[7]
[8]2788
[9]109589269

此步骤即为教材中所说的分配,接下来就是要进行收集,依照桶的编号,将含有数据的桶中的数据依次取出,形成的新的数据记录为:

930 63 83 184 505 278 8 109 589 269

再对这个数组按照十分位进行分配进桶,收集,最后再按照百位进行分配进桶,收集。就可得到最终的排序结果。

public class MyTest2 {
    public static void main(String[] args) {
        int[] arr = {278,109,63,930,589,184,505,269,8,83};
        sortArrays(arr);
        System.out.println(Arrays.toString(arr));

    }

    private static void sortArrays(int[] arr) {
        int[][] temparry = new int[10][arr.length];
        int max = getMax(arr);
        int[] counts = new int[arr.length];
        int len = String.valueOf(max).length();
        for (int i = 0, n = 1; i < len; i++, n *= 10) {
            for (int j = 0; j < arr.length; j++) {
                int i1 = arr[j] / n % 10;
                temparry[i1][counts[i1]++] = arr[j];
            }
            int index=0;
            for (int k = 0; k < counts.length; k++) {
                if (counts[k] != 0) {
                    for (int l = 0; l < counts[k]; l++) {
arr[index]=temparry[k][l];
index++;
                    }
                    counts[k]=0;
                }
            }

        }
    }
        private static int getMax ( int[] arr){
            int max = arr[0];
            for (int i = 1; i < arr.length; i++) {
                if (arr[i] > max) {
                    max = arr[i];
                }
            }
            return max;
        }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值