算法与数据结构全阶班-左程云版(二)基础阶段之3.归并排序和快速排序(下)

简介: 本文主要介绍了两种排序,归并排序和快速排序,归并排序有递归和非递归2种方式实现,快速排序的升级版为荷兰国旗问题。

2.快速排序

Partition过程:

给定一个数组arr,和一个整数num。请把小于等于num的数放在数组的左边,大于num的数放在数组的右边;

要求额外空间复杂度O(1),时间复杂度O(N)。

思路如下:

2345_image_file_copy_125.jpg

Partition过程升级版(荷兰国旗问题):

给定一个数组arr,和一个整数num。请把小于num的数放在数组的左边,等于num的数放在数组的中间,大于num的数放在数组的右边;

要求额外空间复杂度O(1),时间复杂度O(N)。

思路如下:

2345_image_file_copy_126.jpg

两种分区实现如下:

public class PartitionAndQuickSort {
    /*
    普通分区:
    给定一个数组arr和一个整数num,
    请把小于等于num的数放在数组的左边,
    大于num的数放在数组的右边
     */
    public static int partition(int[] arr, int L, int R) {
        if (L > R) {
            return -1;
        }
        if (L == R) {
            return L;
        }
        int lessEqual = L - 1;
        int index = L;
        while (index < R) {
            if (arr[index] <= arr[R]) {
                swap(arr, index, ++lessEqual);
            }
            index++;
        }
        swap(arr, ++lessEqual, R);
        return lessEqual;
    }
    /*
    分区升级版:荷兰国旗:
    给定一个数组arr和一个整数num
    请把小于num的数放在数组的左边,
    等于num的数放在数组的中间,
    大于num的数放在数组的右边
     */
    public static int[] netherlandsFlag(int[] arr, int L, int R) {
        if (L > R) {
            return new int[]{-1, -1};
        }
        if (L == R) {
            return new int[]{L, R};
        }
        int less = L - 1, more = R;
        int index = L;
        while (index < more) {
            if (arr[index] == arr[R]) {
                index++;
            } else if (arr[index] < arr[R]) {
                swap(arr, index++, ++less);
            } else {
                swap(arr, index, --more);
            }
        }
        swap(arr, more, R);
        return new int[]{less + 1, more};
    }
    public static void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }
}

快速排序:

快速排序有3种方式:

(1)利用普通分区算法;

(2)利用荷兰国旗算法;

(3)随机选数与最后一个数交换,再利用荷兰国旗算法。

分析时间复杂度:

随机快排的时间复杂度分析:

1)通过分析知道,划分值越靠近中间,性能越好;越靠近两边,性能越差

2)随机选一个数进行划分的目的就是让好情况和差情况都变成概率事件

3)把每一种情况都列出来,会有每种情况下的时间复杂度,但概率都是1/N

4)那么所有情况都考虑,时间复杂度就是这种概率模型下的长期期望,

时间复杂度O(N*logN),额外空间复杂度O(logN)都是这么来的。

(1)前两种:

最差情况是数组已经有序:

2345_image_file_copy_128.jpg

(2)第三种

一般情况是获取到的随机数在数组中间位置附近,就属于较好的情况:

2345_image_file_copy_129.jpg

2345_image_file_copy_130.jpg

空间复杂度:

2345_image_file_copy_131.jpg

最差情况下是O(N),累加求期望收敛于O(LogN)。

3种快速排序实现如下:

public static void quickSort1(int[] arr) {
    if (null == arr || arr.length < 2) {
        return;
    }
    process1(arr, 0, arr.length-1);
}
public static void process1(int[] arr, int L, int R) {
    if (L >= R) {
        return;
    }
    int M = partition(arr, L, R);
    process1(arr, L, M - 1);
    process1(arr, M + 1, R);
}
public static void quickSort2(int[] arr) {
    if (null == arr || arr.length < 2) {
        return;
    }
    process2(arr, 0, arr.length-1);
}
public static void process2(int[] arr, int L, int R) {
    if (L >= R) {
        return;
    }
    int[] equalArea = netherlandsFlag(arr, L, R);
    process1(arr, L, equalArea[0] - 1);
    process1(arr, equalArea[1]+ 1, R);
}
public static void quickSort3(int[] arr) {
    if (null == arr || arr.length < 2) {
        return;
    }
    process3(arr, 0, arr.length-1);
}
public static void process3(int[] arr, int L, int R) {
    if (L >= R) {
        return;
    }
    swap(arr, (int) (Math.random() * (R + 1)), R);
    int[] equalArea = netherlandsFlag(arr, L, R);
    process1(arr, L, equalArea[0] - 1);
    process1(arr, equalArea[1]+ 1, R);
}

总结

归并排序有很多个应用场景,一般应用在数组中左边的数比右边的数满足某个条件时,进行某个操作,都可以在归并的过程中进行解决。

相关文章
|
2月前
|
存储 监控 安全
企业上网监控系统中红黑树数据结构的 Python 算法实现与应用研究
企业上网监控系统需高效处理海量数据,传统数据结构存在性能瓶颈。红黑树通过自平衡机制,确保查找、插入、删除操作的时间复杂度稳定在 O(log n),适用于网络记录存储、设备信息维护及安全事件排序等场景。本文分析红黑树的理论基础、应用场景及 Python 实现,并探讨其在企业监控系统中的实践价值,提升系统性能与稳定性。
66 1
|
2月前
|
存储 监控 算法
基于跳表数据结构的企业局域网监控异常连接实时检测 C++ 算法研究
跳表(Skip List)是一种基于概率的数据结构,适用于企业局域网监控中海量连接记录的高效处理。其通过多层索引机制实现快速查找、插入和删除操作,时间复杂度为 $O(\log n)$,优于链表和平衡树。跳表在异常连接识别、黑名单管理和历史记录溯源等场景中表现出色,具备实现简单、支持范围查询等优势,是企业网络监控中动态数据管理的理想选择。
77 0
|
5月前
|
算法 搜索推荐
快速排序-数据结构与算法
快速排序(Quick Sort)是一种基于分治法的高效排序算法。其核心思想是通过选择基准(pivot),将数组划分为左右两部分,使得左侧元素均小于基准,右侧元素均大于基准,然后递归地对左右两部分进行排序。时间复杂度平均为 O(n log n),最坏情况下为 O(n²)(如数组已有序)。空间复杂度为 O(1),属于原地排序,但稳定性不佳。 实现步骤包括编写 `partition` 核心逻辑、递归调用的 `quickSort` 和辅助函数 `swap`。优化方法有随机化基准和三数取中法,以减少最坏情况的发生。
295 13
|
6月前
|
算法 Java
算法系列之数据结构-Huffman树
Huffman树(哈夫曼树)又称最优二叉树,是一种带权路径长度最短的二叉树,常用于信息传输、数据压缩等方面。它的构造基于字符出现的频率,通过将频率较低的字符组合在一起,最终形成一棵树。在Huffman树中,每个叶节点代表一个字符,而每个字符的编码则是从根节点到叶节点的路径所对应的二进制序列。
155 3
 算法系列之数据结构-Huffman树
|
6月前
|
算法 Java
算法系列之数据结构-二叉搜索树
二叉查找树(Binary Search Tree,简称BST)是一种常用的数据结构,它能够高效地进行查找、插入和删除操作。二叉查找树的特点是,对于树中的每个节点,其左子树中的所有节点都小于该节点,而右子树中的所有节点都大于该节点。
187 22
|
3天前
|
传感器 机器学习/深度学习 算法
【使用 DSP 滤波器加速速度和位移】使用信号处理算法过滤加速度数据并将其转换为速度和位移研究(Matlab代码实现)
【使用 DSP 滤波器加速速度和位移】使用信号处理算法过滤加速度数据并将其转换为速度和位移研究(Matlab代码实现)
|
5天前
|
机器学习/深度学习 算法 调度
基于NSGA-III算法求解微电网多目标优化调度研究(Matlab代码实现)
基于NSGA-III算法求解微电网多目标优化调度研究(Matlab代码实现)
|
4天前
|
传感器 算法 数据挖掘
基于协方差交叉(CI)的多传感器融合算法matlab仿真,对比单传感器和SCC融合
基于协方差交叉(CI)的多传感器融合算法,通过MATLAB仿真对比单传感器、SCC与CI融合在位置/速度估计误差(RMSE)及等概率椭圆上的性能。采用MATLAB2022A实现,结果表明CI融合在未知相关性下仍具鲁棒性,有效降低估计误差。
|
5天前
|
负载均衡 算法 调度
基于遗传算法的新的异构分布式系统任务调度算法研究(Matlab代码实现)
基于遗传算法的新的异构分布式系统任务调度算法研究(Matlab代码实现)
68 11
|
5天前
|
机器学习/深度学习 传感器 算法
基于全局路径的无人地面车辆的横向避让路径规划研究[蚂蚁算法求解](Matlab代码实现)
基于全局路径的无人地面车辆的横向避让路径规划研究[蚂蚁算法求解](Matlab代码实现)

热门文章

最新文章