常见排序算法

冒泡排序(Bubble Sort)

1.实现过程

有6个数字待排序:a[0] = 4,a[1] =6,a[2] =5,a[3] =3,a[4] =2,a[5] =1

第一次排序:

a[5]<a[0]-->a[0] = 1,a[5] =4;

a[5]<a[1]-->a[1] = 4,a[5] =6;

a[5]>a[2]-->不处理;

a[5]>a[3]-->不处理;

a[5]>a[4]-->不处理;

a[0] = 1,a[1] =4;a[2] =5;a[3] =3;a[4] =2;a[5] =6

这一段保证a[5]为最大值

第二次排序: 

a[4]<a[0]-->a[0] = 1,a[4] =2;

a[4]<a[1]-->a[1] = 2,a[4] =4;

a[4]<a[2]-->a[2] = 4,a[4] =5;

a[4]>a[3]-->不处理;

a[0] = 1;a[1] =2;a[2] =4;a[3] =3;a[4] =5;a[5] =6

这一段保证a[4]<a[5]

第三次排序:

 a[3]>a[0]--不处理;

a[3]>a[1]-->不处理;

a[3]<a[2]-->a[2] = 3,a[4] =4;

a[0] = 1;a[1] =2;a[2] =3;a[3] =4;a[4] =5;a[5] =6

这一段保证a[3]<a[4]<a[5]

 由此可知,若对n个数字进行冒泡排序,第一次要排n-1趟,第二次要排n-2趟,第n-1次要排1趟。时间复杂度:

(n-1)+(n-2)+(n-3)+...+1=((n-1)+1)*(n-1)/2=n(n-1)/2

2.代码示例

    @ResponseBody
    @ApiOperation("冒泡排序")
    @PostMapping("/bubbleSort")
    public int[] bubbleSort(@RequestBody int[] a) {
        for (int i = a.length - 1; i > 0; i--) {
            // 将a[0...i]中最大的数据放在末尾
            for (int j = 0; j < i; j++) {
                if (a[j] > a[j + 1]) {
                    int tmp = a[j];
                    a[j] = a[j + 1];
                    a[j + 1] = tmp;
                }
            }
        }
        return a;
    }

    @ResponseBody
    @ApiOperation("冒泡排序改进版")
    @PostMapping("/greatBubbleSort")
    public int[] greatBubbleSort(@RequestBody int[] a) {
        Boolean flag;
        for (int i = a.length - 1; i > 0; i--) {
            flag = Boolean.FALSE;
            // 将a[0...i]中最大的数据放在末尾
            for (int j = 0; j < i; j++) {
                if (a[j] > a[j + 1]) {
                    int tmp = a[j];
                    a[j] = a[j + 1];
                    a[j + 1] = tmp;
                    flag = Boolean.TRUE;
                }
            }
            if (Boolean.FALSE.equals(flag)) {
                break;
            }
        }
        return a;
    }

快速排序(Quick Sort)

1.实现过程

  • 从数列中挑出一个基准值。
  • 将所有比基准值小的摆放在基准前面,所有比基准值大的摆在基准的后面(相同的数可以到任一边);在这个分区退出之后,该基准就处于数列的中间位置。
  • 递归地把"基准值前面的子数列"和"基准值后面的子数列"进行排序。

有6个数字待排序:a[0] = 4;a[1] =6;a[2] =5;a[3] =3;a[4] =2;a[5] =1

基准值:a[0]=4

①从右往左找到比4小的值并交换位置 4>a[5] a[0]与a[5]交换

a[0] = 1;a[1] =6;a[2] =5;a[3] =3;a[4] =2;a[5] =4

②从左往右找到比4大的值并交换位置 a[1]>4 a[2]与a[5]交换

a[0] = 1;a[1] =4;a[2] =5;a[3] =3;a[4] =2;a[5] =6

③从右往左找到比4小的值并交换位置 a[4]<4 a[1]与a[4]交换

a[0] = 1;a[1] =3;a[2] =5;a[3] =2;a[4] =4;a[5] =6

④从左往右找到比4大的值并交换位置 a[4]>4 a[2]与a[4]交换

a[0] = 1;a[1] =3;a[2] =4;a[3] =2;a[4] =5;a[5] =6

⑤从右往左找到比4小的值并交换位置 a[3]<4 a[2]与a[3]交换

a[0] = 1;a[1] =3;a[2] =2;a[3] =4;a[4] =5;a[5] =6

⑤第一趟结束

由此可知,若对n个数字进行冒泡排序,快速排序的时间复杂度在最坏情况下是O(N2),平均的时间复杂度是O(N*lgN)。

2.代码示例

/**
     * 快速排序: Java
     *
     * @author sx
     * @date 2024/03/19
     */
    @ResponseBody
    @ApiOperation("快速排序")
    @PostMapping("/quickSort")
    public List<Integer> QuickSort(@RequestBody int[] a) {
        log.info("before sort:");
        List<Integer> listBefore = Arrays.stream(a).boxed().collect(Collectors.toList());
        log.info(listBefore);
        int[] sort = sort(a, 0, a.length - 1);
        log.info("after  sort:");
        List<Integer> listAfter = Arrays.stream(sort).boxed().collect(Collectors.toList());
        log.info(listAfter);
        return listAfter;
    }

    public int[] sort(int[] a, int l, int r) {
        /*
         * 快速排序
         *
         * 参数说明:
         *     a -- 待排序的数组
         *     l -- 数组的左边界(例如,从起始位置开始排序,则l=0)
         *     r -- 数组的右边界(例如,排序截至到数组末尾,则r=a.length-1)
         */
        if (l < r) {
            int i, j, x;
            i = l;
            j = r;
            //基准数
            x = a[i];
            while (i < j) {
                // 从右向左找第一个小于x的数
                while (a[j] > x) {
                    j--;
                }
                if (i < j) {
                    a[i++] = a[j];
                }
                // 从左向右找第一个大于x的数
                while (i < j && a[i] < x) {
                    i++;
                }
                if (i < j) {
                    a[j--] = a[i];
                }
            }
            a[i] = x;
            sort(a, l, i - 1); /* 递归调用 */
            sort(a, i + 1, r); /* 递归调用 */
        }
        return a;
    }

插入排序(Insertion Sort)

1.实现过程

把n个待排序的元素看成为一个有序表和一个无序表。开始时有序表中只包含1个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,将它插入到有序表中的适当位置,使之成为新的有序表,重复n-1次可完成排序过程。

有6个数字待排序:a[0] = 4;a[1] =6;a[2] =5;a[3] =3;a[4] =2;a[5] =1

第一趟:

有序表:a[0] = 4;无序表:a[1] =6;a[2] =5;a[3] =3;a[4] =2;a[5] =1

①a[1]>a[0],有序表:a[0] = 4;a[1] =6 无序表:a[2] =5;a[3] =3;a[4] =2;a[5] =1

②a[2]<a[1],有序表:a[0] = 4;a[1] =5,a[2] =6 无序表:a[3] =3;a[4] =2;a[5] =1

a[1]>a[0],不改变

③a[3]<a[2],有序表:a[0] = 4;a[1] =5,a[2] =3,a[3] =6 无序表:a[4] =2;a[5] =1

a[2]<a[1],有序表:a[0] = 4;a[1] =3,a[2] =5,a[3] =6 无序表:a[4] =2;a[5] =1

a[1]<a[0],有序表:a[0] = 3;a[1] =4,a[2] =5,a[3] =6 无序表:a[4] =2;a[5] =1

④a[4]<a[3],有序表:a[0] = 3;a[1] =4,a[2] =5,a[3] =2,a[4] =6 无序表:a[5] =1

a[3]<a[2],有序表:a[0] = 3;a[1] =4,a[2] =2,a[3] =5,a[4] =6 无序表:a[5] =1

a[2]<a[1],有序表:a[0] = 3,a[1] =2,a[2] =4,a[3] =5,a[4] =6  无序表:a[5] =1

a[1]<a[0],有序表:a[0] =2,a[1] =3,a[2] =4,a[3] =5,a[4] =6  无序表:a[5] =1

⑤a[5]<a[4],有序表:a[0] = 2,a[1] =3,a[2] =4,a[3] =5,a[4] =1,a[5] =6 

a[4]<a[3],有序表:a[0] = 2,a[1] =3,a[2] =4,a[3] =1,a[4] =5,a[5] =6

a[3]<a[2],有序表:a[0] = 2,a[1] =3,a[2] =1,a[3] =4,a[4] =5,a[5] =6

a[2]<a[1],有序表:a[0] = 2,a[1] =1,a[2] =3,a[3] =4,a[4] =5,a[5] =6 

a[1]<a[0],有序表:a[0] = 1,a[1] =2,a[2] =3,a[3] =4,a[4] =5,a[5] =6 

被排序的数列中有n个数。遍历一趟的时间复杂度是O(n),需要遍历 n-1次。因此,直接插入排序的时间复杂度是O(n^2)

2.代码示例

/**
     * 插入排序
     *
     * @author sx
     * @date 2024/03/19
     */
    @ResponseBody
    @ApiOperation("插入排序")
    @PostMapping("/insertSort")
    public List<Integer> InsertSort(@RequestBody int[] a) {

        log.info("before sort:");
        List<Integer> listBefore = Arrays.stream(a).boxed().collect(Collectors.toList());
        log.info(listBefore);
        //开始排序
        int i, j, k;
        for (i = 1; i < a.length; i++) {
            //为a[i]在前面的a[0...i-1]有序区间中找一个合适的位置
            for (j = i - 1; j >= 0; j--) {
                if (a[j] < a[i]) {
                    break;
                }
            }
            //如找到了一个合适的位置
            if (j != i - 1) {
                //将比a[i]大的数据向后移
                int temp = a[i];
                for (k = i - 1; k > j; k--) {
                    a[k + 1] = a[k];
                }
                //将a[i]放到正确位置上
                a[k + 1] = temp;
            }
        }
        log.info("after  sort:");
        List<Integer> listAfter = Arrays.stream(a).boxed().collect(Collectors.toList());
        log.info(listAfter);
        return listAfter;
    }

Shell排序(Shell Sort)

1.实现过程

2.代码示例

选择排序(Selection sort)

1.实现过程

2.代码示例

堆排序(Heap Sort)

1.实现过程

2.代码示例

归并排序(Merge Sort)

1.实现过程

2.代码示例

桶排序(Bucket Sort)

1.实现过程

2.代码示例

基数排序(Radix Sort)

1.实现过程

2.代码示例

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

sunnxin

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

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

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

打赏作者

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

抵扣说明:

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

余额充值