合并排序与快速排序算法


算法介绍

合并排序与快速排序是排序算法中常用的两种排序算法,合并排序把数据分为两段,从两段中逐个选最小的元素移入新数据的末尾;快速排序是在序列中挑选一个元素(本文中为首位元素),将小于该元素的放在该元素之前,大于的放于该元素之后,再分别对元素前后两段序列进行排序。

代码实现

1.合并排序

实现思路: 将数组通过折中不断细分成若干子序列,对最短两元素的子序列进行两两比较后得到若干有序序列,不断两两合并这些子序列,并通过比较两个序列首部元素大小进行排列,最终合并得到有序的序列。
时间复杂度: O(nlogn)
空间复杂度: O(n)
代码如下:

public static void mergeSort(int[] arr, int left, int right) {
        if (left < right) {
            int i = (left + right) / 2;
            //递归调用,对左侧进行排序
            mergeSort(arr, left, i);
            //递归调用,对右侧进行排序
            mergeSort(arr, i + 1, right);

            merge(arr, left, i, right);
        }
    }

    //arr[1:m] arr[m+1:r]
    public static void merge(int[] arr, int l, int m, int r) {
        int len1 = m - l + 1;
        int len2 = r - m;
        //构造数组left,right分别存储左右侧元素
        int[] left = new int[len1];
        int[] right = new int[len2];
        for (int n1 = 0; n1 < len1; n1++) {
            left[n1] = arr[l + n1];
        }
        for (int n1 = 0; n1 < len2; n1++) {
            right[n1] = arr[m + 1 + n1];
        }
        int i = 0, j = 0;
        int k = l;
        //将数组元素值两两比较,并合并到arr数组相应位置
        while (i < len1 && j < len2)
        {
            if (left[i] <= right[j])
                arr[k++] = left[i++];
            else
                arr[k++] = right[j++];
        }
        //判断超出部分并进行拼接
        if (i >= len1) {
            for (int n1 = j; n1 < len2; n1++) {
                arr[k++] = right[n1];
            }
        }
        if (j >= len2) {
            for (int n1 = i; n1 < len1; n1++) {
                arr[k++] = left[n1];
            }
        }
    }

2.快速排序

实现思路: 将数组头部元素与后续元素进行比较,通过首尾双指针(首指针找大于头部元素的元素,尾指针找小于头部元素的元素,找到则进行交换,直到首指针等于尾指针,最后将头部元素与首指针元素进行交换)使得头部元素(已换位)前的元素均小于自身,后的元素均大于自身,然后对头部元素(已换位)前的元素子序列、后的元素子序列不断重复以上过程,直到子序列长度等于1。
时间复杂度: O(nlogn)
空间复杂度: O(logn)
代码如下:

public static void quickSort(int[] arr, int begin, int end) {
        //长度小于1结束递归
        if (begin > end) {
            return;
        }
        int tmp = arr[begin];
        int i = begin, j = end;
        //首指针i等于尾指针j结束循环
        while (i != j) {
            //j在前面,因为尾指针j先出发
            //从后往前找,直到找到比tmp小的元素
            while (arr[j] >= tmp && i < j) {
                j--;
            }
            //从前往后找,直到找到比tmp大的元素
            while (arr[i] <= tmp && i < j) {
                i++;
            }
            //将两元素进行调换
            int t = arr[i];
            arr[i] = arr[j];
            arr[j] = t;
        }
        //将头元素与中间元素进行调换
        arr[begin] = arr[i];
        arr[i] = tmp;
        //对左边进行快速排序
        quickSort(arr, begin, i - 1);
        //对右边进行快速排序
        quickSort(arr, i + 1, end);
    }

总结

实践出真知,只有自己动手写才能充分感受到算法的巧妙与设计难度,在一步一步代码实现的过程中充分理解算法的思想,不断巩固,不断进步!最后补充常用排序算法及其复杂度分析,具体如下图:
常用排序算法

参考《算法程序设计 》

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值