Java——常见的几种排序算法

一、冒泡排序

每次冒泡过程都是从数列的第一个元素开始,然后依次和剩余的元素进行比较, 跟列队一样, 从左到右两两相邻的元素比大小, 高的就和低的换一下位置. 最后最高(值最大)的肯定就排到后面了.

但是这只是把最高的排到后面了, 还得找出第二高的, 于是又从第一个开始两两比较, 高的往后站, 然后第二高的也到后面了.

然后是第三高的再往后排…
在这里插入图片描述

 

public class JavaSort {
    public static void main(String[] args) {
        int[] arr ={4,1,3,6,2,5};

        for (int i = 1; i < arr.length; i++) {  //外循环控制冒泡次数
            for (int j = 0; j < arr.length-1; j++) {    //内循环用来控制冒泡一层层到最后
                if (arr[j]>arr[j+1]){   //如果前一个数比后一个数大,两者交换
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }

        for (int i : arr) {
            System.out.println(i);
        }
    }
}

二、 冒泡排序改进版

在这个版本中,改动了两点

  1. 第一点是加入了一个布尔值,判断第二层循环中的调换有没有执行,如果没有进行两两调换,说明后面都已经排好序了,已经不需要再循环了,直接跳出循环,排序结束.
  2. 第二点是第二层循环不再循环到arr.length - 1,因为外面的i循环递增一次,说明数组最后就多了一个排好序的大泡泡.第二层循环也就不需要到最末尾一位了,可以提前结束循环
public class JavaSort {
    public static void main(String[] args) {
        int[] arr ={4,1,3,6,2,5};

        for (int i = 1; i < arr.length-1; i++) {
            //初始化一个布尔值
            boolean flag = true;
            for (int j = 0; j < arr.length-1; j++) {
                if (arr[j] > arr[j+1]){
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j] = temp;
                    //改变 flag
                    flag = false;
                }
            }
            if (flag){
                break;
            }
        }

        for (int i : arr) {
            System.out.println(i);
        }
    }
}

三、选择排序

选择排序也是一种简单直观的排序算法,实现原理比较直观易懂:
首先在未排序数列中找到最小元素,然后将其与数列的首部元素进行交换,然后,在剩余未排序元素中继续找出最小元素,将其与已排序数列的末尾位置元素交换。以此类推,直至所有元素圴排序完毕。

在这里插入图片描述

 

public class JavaSort {
    public static void main(String[] args) {
        int[] arr ={4,1,3,6,2,5};

        for (int i = 0; i < arr.length-1; i++) {
            int min = i;    //假设i为当前轮的最小值的下标
            for (int j = i+1; j < arr.length; j++) {
                if (arr[j] < arr[min]){
                    //找到当前遍历区间最小的值的下标
                    min = j;
                }
            }
            if (min != i){
                //将最小值交换至本轮的起始位置
                int temp = arr[min];
                arr[min] = arr[i];
                arr[i] = temp;
            }
        }

        for (int i : arr) {
            System.out.println(i);
        }
    }
}

四、插入排序 

一次插入排序的操作过程:
  将待插元素,依次与已排序好的子数列元素从后到前进行比较,如果当前元素值比待插元素值大,则将移位到与其相邻的后一个位置,否则直接将待插元素插入当前元素相邻的后一位置,因为说明已经找到插入点的最终位置

在这里插入图片描述

 

public class JavaSort {
    public static void main(String[] args) {
        int[] arr ={4,1,3,6,2,5};

        for (int i = 1; i < arr.length; i++) {
            //挖出一个要用来插入的值,同时位置上留下一个可以存新的值的坑
            int temp = arr[i];
            int j = i -1;
            //在前面有一个或连续多个值比temp大的时候,一直循环往前面找,将temp插入到这串值前面
            while (j >= 0 && arr[j] > temp){
                //当arr[j]比temp大的时候,将j向后移一位,正好填到坑中
                arr[j+1] = arr[j];
                j--;
            }
            //将temp插入到最前面
            arr[j+1] = temp;
        }

        for (int i : arr) {
            System.out.println(i);
        }
    }
}

五、分治排序法,快速排序法

简单的说, 就是设置一个标准值, 将大于这个值的放到右边(不管排序), 将小于这个值的放到左边(不管排序), 那么这样只是区分了左小右大, 没有排序, 没关系, 左右两边再重复这个步骤.直到不能分了为止.
详细说就是:

  1. 选择待排数列的首部第一个元素为基准元素x,设置两指针,分别指向数列首尾部位置,假设两指针分别设为i和j。
  2. 每次遍历的过程是这样的,首先从右到左遍历指针j所指向的元素,直到j指向的元素值小于基准元素x时,停止遍历,将其放到i的位置(因为i的值已经拷贝成了基准x腾出了位置)
  3. i往右挪一步, i++,接着轮到指针i从左到右遍历,直到i所指向的元素值大于基准元素x时,停止遍历,将其放到j的位置(因为上面一步j的值已经占用到了i的位置,腾出位置了)
  4. 依此类推,两边轮流遍历, 直到指针i与指针j相等或者大于(实际肯定是i==j)时,停止外部循环。此时必定左边都是比x小的, 右边是比x大的.
  5. 最后直接将基准元素x直接放置于指针i所指向的位置即可
  6. 完成分区操作, 从i的位置一分为二, 左边和右边再递归执行上面的操作. 层层细分

接下来,我们通过示图来展示上述分区算法思路的过程:

在这里插入图片描述

public class JavaSort {
    static void quickSort(int[] arr,int begin,int end){
        //先定义两个参数接收排序起始值和结束值
        int a = begin;
        int b = end;
        //先判断a是否大于b

        if (a >= b) {
            //没必要排序
            return;
        }
        //基准数,默认设置为第一个值
        int x = arr[a];

        //循环
        while (a < b) {
            //从后往前找,找到一个比基准数x小的值,赋给arr[a]
            //如果a和b的逻辑正确--a<b ,并且最后一个值arr[b]>x,就一直往下找,直到找到后面的值大于x
            while (a < b && arr[b] >= x) {
                b--;
            }
            //跳出循环,两种情况,一是a和b的逻辑不对了,a>=b,这时候排序结束.二是在后面找到了比x小的值
            if (a < b) {
                //将这时候找到的arr[b]放到最前面arr[a]
                arr[a] = arr[b];
                //排序的起始位置后移一位
                a++;
            }

            //从前往后找,找到一个比基准数x大的值,放在最后面arr[b]
            while (a < b && arr[a] <= x) {
                a++;
            }
            if (a < b) {
                arr[b] = arr[a];
                //排序的终止位置前移一位
                b--;
            }
        }
        //跳出循环 a < b的逻辑不成立了,a==b重合了,此时将x赋值回去arr[a]
        arr[a] = x;
        //调用递归函数,再细分再排序
        quickSort(arr,begin,b-1);
        quickSort(arr,a+1,end);

    }

    public static void main(String[] args) {
        int[] arr ={4,1,3,6,2,5};

        quickSort(arr,0,arr.length-1);
        for (int i : arr) {
            System.out.println(i);
        }
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vicky_Tang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值