深入解析经典排序算法:原理、实现与优化

news2024/11/25 14:04:39

文章目录

      • 6. 堆排序(Heap Sort)
        • 原理
        • Java 实现
      • 7. 希尔排序(Shell Sort)
        • 原理
        • Java 实现
      • 8. 计数排序(Counting Sort)
        • 原理
        • Java 实现
      • 9. 基数排序(Radix Sort)
        • 原理
        • Java 实现

深入浅出:Java 中的经典排序算法详解与实现

6. 堆排序(Heap Sort)

原理

堆排序算法是一种高效的排序方法,其核心在于利用了堆的数据结构特性。堆是一种特殊的完全二叉树,可以分为最大堆和最小堆两种形式。在最大堆中,每个父节点的值总是大于或等于其两个子节点的值;而在最小堆中,每个父节点的值总是小于或等于其两个子节点的值。这种性质使得堆的根节点总是整个堆中的最大值或最小值。

堆排序算法的过程主要分为两个阶段:

  1. 构建初始堆:首先将待排序的无序序列构建成一个最大堆(假设升序排列),此时堆顶元素即为序列中的最大值。
  2. 排序处理:将堆顶元素与序列最后一个元素交换位置,然后将剩余的序列重新调整为最大堆,重复这一过程,直到所有元素都被排序。
Java 实现
public class HeapSort {
    public static void sort(int[] arr) {
        int n = arr.length;

        // 构建最大堆
        for (int i = n / 2 - 1; i >= 0; i--) {
            heapify(arr, n, i);
        }

        // 开始排序
        for (int i = n - 1; i > 0; i--) {
            // 移动当前根节点至数组末尾
            int temp = arr[0];
            arr[0] = arr[i];
            arr[i] = temp;

            // 对剩余未排序的元素重新构建最大堆
            heapify(arr, i, 0);
        }
    }

    private static void heapify(int[] arr, int n, int i) {
        int largest = i; // 初始化最大值为根节点
        int left = 2 * i + 1; // 左子节点
        int right = 2 * i + 2; // 右子节点

        // 比较左子节点是否大于根节点
        if (left < n && arr[left] > arr[largest]) {
            largest = left;
        }

        // 比较右子节点是否大于当前最大值
        if (right < n && arr[right] > arr[largest]) {
            largest = right;
        }

        // 若最大值不是根节点,则交换它们的位置,并继续向下调整
        if (largest != i) {
            int swap = arr[i];
            arr[i] = arr[largest];
            arr[largest] = swap;

            heapify(arr, n, largest);
        }
    }
}

7. 希尔排序(Shell Sort)

原理

希尔排序是对直接插入排序的优化,它通过将原始列表分割成多个子列表,每个子列表分别进行插入排序,这样做的目的是为了减少数据项之间的移动次数,从而提高排序效率。希尔排序的关键在于选择合适的间隔序列,间隔序列的选择直接影响到排序的性能。

Java 实现
public class ShellSort {
    public static void sort(int[] arr) {
        int n = arr.length;
        int gap = n / 2;

        // 控制间隔序列
        while (gap > 0) {
            for (int i = gap; i < n; i++) {
                int temp = arr[i];
                int j = i;
                // 插入排序的核心部分,使用间隔进行比较和交换
                while (j >= gap && arr[j - gap] > temp) {
                    arr[j] = arr[j - gap];
                    j -= gap;
                }
                arr[j] = temp;
            }
            // 减小间隔
            gap /= 2;
        }
    }
}

8. 计数排序(Counting Sort)

原理

计数排序是一种线性时间复杂度的非比较型排序算法,特别适合用于数据范围已知且较小的情况。它的工作原理是创建一个额外的计数数组来记录输入数组中每个元素出现的次数,然后根据计数数组重构出排序后的数组。

Java 实现
public class CountingSort {
    public static void sort(int[] arr) {
        int max = Integer.MIN_VALUE;
        int min = Integer.MAX_VALUE;

        // 寻找最大值和最小值
        for (int num : arr) {
            max = Math.max(max, num);
            min = Math.min(min, num);
        }

        // 创建计数数组并初始化
        int range = max - min + 1;
        int[] count = new int[range];

        // 计算每个元素出现的次数
        for (int num : arr) {
            count[num - min]++;
        }

        // 重构排序后的数组
        int index = 0;
        for (int i = 0; i < range; i++) {
            while (count[i] > 0) {
                arr[index++] = i + min;
                count[i]--;
            }
        }
    }
}

9. 基数排序(Radix Sort)

原理

基数排序是一种非比较型的排序算法,主要用于整数排序。它通过对整数的每一位数字进行独立的排序来实现整体排序的目的。基数排序有两种主要的方式:最高有效位(MSD)和最低有效位(LSD)。LSD 方法通常更常用,因为它可以通过简单的计数排序或桶排序来实现。

基数排序的基本步骤包括:

  1. 确定排序的最大位数:找到数组中的最大值,以确定需要排序的位数。
  2. 按位排序:从最低位开始,对每一位上的数字进行排序,通常使用计数排序作为子过程。
  3. 合并结果:经过多次按位排序后,数组已经是有序状态。
Java 实现
public class RadixSort {
    public static void sort(int[] arr) {
        int max = getMax(arr); // 获取数组中最大的数

        // 对每个位数进行排序
        for (int exp = 1; max / exp > 0; exp *= 10) {
            countSort(arr, exp);
        }
    }

    private static void countSort(int[] arr, int exp) {
        int n = arr.length;
        int[] output = new int[n]; // 输出数组
        int[] count = new int[10]; // 计数数组

        // 计算每个位数上的数字出现次数
        for (int i = 0; i < n; i++) {
            int index = (arr[i] / exp) % 10;
            count[index]++;
        }

        // 修改 count 数组,使其包含实际位置信息
        for (int i = 1; i < 10; i++) {
            count[i] += count[i - 1];
        }

        // 构建输出数组
        for (int i = n - 1; i >= 0; i--) {
            int index = (arr[i] / exp) % 10;
            output[count[index] - 1] = arr[i];
            count[index]--;
        }

        // 将输出数组复制回原数组
        for (int i = 0; i < n; i++) {
            arr[i] = output[i];
        }
    }

    private static int getMax(int[] arr) {
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
        }
        return max;
    }
}

这些排序算法各有特点,适用于不同场景下的排序需求。在选择排序算法时,应考虑数据的具体特征、大小以及性能要求等因素。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2247341.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文小言1:

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

Oracle 23ai 对应windows版本安装配置PLSQL导入pde文件navicat连接Oracle

因为有一个pde文件需要查看里面的数据&#xff0c;所以这次需要配置本地oracle数据库&#xff0c;并且导入数据&#xff0c;因为还有navicat&#xff0c;所以就想用navicat去连接查看。 1、找到官网。 Get Started with Oracle Database 23ai | Oracle 2、下载windows版本。…

【热门主题】000062 云原生后端:开启高效开发新时代

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 【热…

Python 版本的 2024详细代码

2048游戏的Python实现 概述&#xff1a; 2048是一款流行的单人益智游戏&#xff0c;玩家通过滑动数字瓷砖来合并相同的数字&#xff0c;目标是合成2048这个数字。本文将介绍如何使用Python和Pygame库实现2048游戏的基本功能&#xff0c;包括游戏逻辑、界面绘制和用户交互。 主…

spf算法、三类LSA、区间防环路机制/规则、虚连接

1.构建spf树&#xff1a; 路由器将自己作为最短路经树的树根根据Router-LSA和Network-LSA中的拓扑信息,依次将Cost值最小的路由器添加到SPF树中。路由器以Router ID或者DR标识。广播网络中DR和其所连接路由器的Cost值为0。SPF树中只有单向的最短路径,保证了OSPF区域内路由计管不…

(二)手势识别——动作模型训练【代码+数据集+python环境(免安装)+GUI系统】

&#xff08;二&#xff09;手势识别——动作模型训练【代码数据集python环境&#xff08;免安装&#xff09;GUI系统】 背景意义 随着互联网的普及和机器学习技术的进一步发展&#xff0c;手势识别技术开始使用深度学习等方法进行手势识别&#xff0c;如Convolutional Neural…

React的基本知识:事件监听器、Props和State的区分、改变state的方法、使用回调函数改变state、使用三元运算符改变state

这篇教学文章涵盖了大量的React基本知识。 包括&#xff1a; 事件监听器Props和State的区分改变state的方法使用回调函数改变state使用三元运算符改变state处理state中的数组处理state中的object条件渲染 &&条件渲染 三元运算符React中的forms 1. Event Listeners 在…

JavaScript练习——文本与图形

要求实现下面这个效果&#xff1a; 观察图片&#xff0c;我们的需求如下&#xff1a; 准备画布和上下文&#xff1a;在开始绘制之前&#xff0c;需要有一个HTML5 <canvas> 元素&#xff0c;并且获取其绘图上下文&#xff08;context&#xff09;&#xff0c;这是进行绘图…

【线程】线程安全问题及解决措施

【线程】线程安全问题及解决措施 前言一、由“随机调度”引起的线程安全问题1.1现象1.2 原因1.3 解决办法1.4 不当加锁造成的死锁问题 二、由“系统优化”引起的线程安全问题2.1 内存可见性问题 / 指令重排序问题2.2 解决方案 前言 何为线程安全&#xff0c;即某段代码无论在单…

[开源]3K+ star!微软Office的平替工具,跨平台,超赞!

大家好&#xff0c;我是JavaCodexPro&#xff01; 数字化的当下&#xff0c;高效的办公工具是提升工作效率的关键&#xff0c;然而大家想到的一定是 Microsoft Office 办公软件&#xff0c;然而价格也是相当具有贵的性价比。 今天JavaCodexPro给大家分享一款超棒的开源办公套…

【大数据分析机器学习】分布式机器学习

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈智能大数据分析 ⌋ ⌋ ⌋ 智能大数据分析是指利用先进的技术和算法对大规模数据进行深入分析和挖掘&#xff0c;以提取有价值的信息和洞察。它结合了大数据技术、人工智能&#xff08;AI&#xff09;、机器学习&#xff08;ML&a…

SOL链上的 Meme 生态发展:从文化到创新的融合#dapp开发#

一、引言 随着区块链技术的不断发展&#xff0c;Meme 文化在去中心化领域逐渐崭露头角。从 Dogecoin 到 Shiba Inu&#xff0c;再到更多细分的 Meme 项目&#xff0c;这类基于网络文化的加密货币因其幽默和社区驱动力吸引了广泛关注。作为近年来备受瞩目的区块链平台之一&…

一篇保姆式centos/ubuntu安装docker

前言&#xff1a; 本章节分别演示centos虚拟机&#xff0c;ubuntu虚拟机进行安装docker。 上一篇介绍&#xff1a;docker一键部署springboot项目 一&#xff1a;centos 1.卸载旧版本 yum remove docker docker-client docker-client-latest docker-common docker-latest doc…

Dubbo源码解析-Dubbo的线程模型(九)

一、Dubbo线程模型 首先明确一个基本概念&#xff1a;IO 线程和业务线程的区别 IO 线程&#xff1a;配置在netty 连接点的用于处理网络数据的线程&#xff0c;主要处理编解码等直接与网络数据 打交道的事件。 业务线程&#xff1a;用于处理具体业务逻辑的线程&#xff0c;可以…

前端全栈 === 快速入 门 Redis

目录 简介 通过 docker 的形式来跑&#xff1a; set、get 都挺简单&#xff1a; incr 是用于递增的&#xff1a; keys 来查询有哪些 key: redis insight GUI 工具。 list 类型 left push rpush lpop 和 rpop 自然是从左边和从右边删除数据。​编辑 如果想查看数据…

Python MySQL SQLServer操作

Python MySQL SQLServer操作 Python 可以通过 pymysql 连接 MySQL&#xff0c;通过 pymssql 连接 SQL Server。以下是基础操作和代码实战示例&#xff1a; 一、操作 MySQL&#xff1a;使用 pymysql python 操作数据库流程 1. 安装库 pip install pymysql2. 连接 MySQL 示例 …

编程语言之C++诞生记!

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于C诞生的相关内容&#xff01; 关于【C诞…

核心差异:知识VS文档管理(+工具软件安利)

在讨论知识管理和文档管理时&#xff0c;我们经常会听到这两种说法被混淆使用。然而&#xff0c;它们各自服务于不同的目的&#xff0c;这一点至关重要。 想象一下&#xff0c;你是一名项目经理&#xff0c;面临以下两项任务&#xff1a; 存储最新的项目计划捕捉团队讨论中获…

医院挂号就诊系统(源码+数据库+报告)

基于SpringBoot的医院挂号就诊系统&#xff0c;系统包含三种角色&#xff1a;管理员、医生、用户,系统分为前台和后台两大模块&#xff0c;主要功能如下。 前台&#xff1a; - 首页&#xff1a;展示医院相关信息、推荐医生等内容。 - 健康教育&#xff1a;提供健康知识、文章等…

【热门主题】000065 探索人工智能学习框架:开启智能未来的钥匙

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 【热…