Java常见排序

1、冒泡排序(从小到大排序)

相邻的元素两两比较,小的放左边,大的放右边

第一轮比较完毕之后,最大值就已经确定了,第二轮比第一轮少循环一次,后面以此类推

如果数据中有n个数据,我们只需要比较n-1轮的代码即可

/**
         * 冒泡排序
         * */

        //定义数组
        int[] arr={2,4,5,3,1};

        //外循环,表示我要执行多消耗轮,如果 有n个数据,就执行n-1轮
        for (int i = 0; i < arr.length-1; i++) {
            //内循环:表示每一轮中,我如何比较并找到当前的最大值
            //-1:为了预防索引越界
            //-i:提高效率,每一轮执行的次数比上一轮少一次
            for (int j = 0; j < arr.length-1-i; j++) {
                if(arr[j]>arr[j+1]){
                    int temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                }
            }
        }
        System.out.println(Arrays.toString(arr));

2、选择排序(从小到大排序)

从0索引开始,跟后面的元素一一比较

小的放前面,大的放后面

第一轮结束之后,最小的数据已经确定

第二轮循环从1索引开始以此类推

 //选择排序
        int[] arr={3,5,1,4,2};

        //外循环:几轮
        //i,表示在这轮中,我要拿着哪个索引上的数据跟后面的数据一一对比
        for (int i = 0; i < arr.length; i++) {
                //内循环:每一轮我要干什么
            //拿着i跟i后面的数据进行比较
            for (int j = i+1; j < arr.length; j++) {
                if(arr[i]>arr[j]){
                    int temp=arr[i];
                    arr[i]=arr[j];
                    arr[j]=temp;

                }
            }
        }

3、插入排序

将0索引的元素到n索引的元素看做是有序的,把n+1索引的元素到最后一个当成是无序的,遍历无序的数据,将遍历到的元素插入有序序列中适当的位置,如遇到相同的数据,插在后面

n的范围:0~最大索引

 //插入排序
        int[] arr={3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};

//1.找到无序的那一组数据是从哪个索引开始
        int start=-1;
        for (int i = 0; i < arr.length; i++) {
            if(arr[i]>arr[i+1]){//表示有序的那一组数据,到哪里结束
                start=i+1;
                break;
            }
        }

        //遍历从start开始到最后一个元素,依次得到无序的那一组数据的每一个元素
        for (int i = start; i < arr.length; i++) {
            //记录当前要插入数据的索引
            int j=i;
            while(j>0&&arr[j]<arr[j-1]){
                //交换位置
                int temp=arr[j];
                arr[j]=arr[j-1];
                arr[j-1]=temp;
                j--;
            }
        }
        System.out.println(Arrays.toString(arr));

4、递归算法

递归是指方法中调用方法本身的现象,把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解

递归一定要有出口,否则就会出现内存溢出。

例子:求1-100之间的和

public class Test04 {
    public static void main(String[] args) {
        //递归算法 1-100之间的和
        //拆问题
        //1-100的和=100+(1-99之间的和)
        //1-99的和=99+(1-98之间的和)
        //1-98的和=98+(1-97之间的和)
        //...
        //1-2的和=2+(1-1之间的和)
        //1-1的和=1(递归的出口)
        System.out.println(getSum(100));
    }

    public static int getSum(int num){
        if(num==1){
            return 1;
        }
        return num+getSum(num-1);
    }
}

5、快速排序

第一轮,把0索引的数字作为基准数,确定基准数在数组中的正确位置,比基准数小的全部在左边,比基准数大的全部在右边

public class Test06 {
    public static void main(String[] args) {
        //快速排序
        int[] arr={6,1,2,7,9,3,4,5,10,8};
        quickSort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }

    /***
     * 参数1:要排序的数组
     * 参数2:要排序 数组的起始位置
     * 参数3:要排序数组的结束索引
     */
    public static  void quickSort(int[] arr,int i,int j){
        //定义两个变量记录要查找的范围
        int start=i;
        int end=j;
        if(start>end){//递归出口
            return;
        }

        //记录基准数
        int baseNum=arr[i];
        //利用循环找到要交换的数据
        while (start!=end){
            //利用end,从后往前找,找到比基准数要小的数据
            while (true){
                if(end<=start||arr[end]<baseNum){
                    break;
                }
                end--;
            }
            //利用start,从前往后找,找到比基准数要大的数据
            while (true){
                if(end<=start||arr[start]>baseNum){
                    break;
                }
                start++;
            }
            //把end和start指向的元素进行交换
            int temp=arr[start];
            arr[start]=arr[end];
            arr[end]=temp;

        }
        //当start和end指向了同一个元素的时候,那么上面的循环就会结束
        //表示已经找到了基准数在数组中应存入的位置
        //基准数归位
        int temp=arr[i];
        arr[i]=arr[start];
        arr[start]=temp;

        //确定6左边的范围,重复刚刚的操作
        quickSort(arr,i,start-1);
        quickSort(arr,start+1,j);
    }
}

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值