八种经典排序算法

以下是八种经典排序算法的介绍,包括它们的基本思想、时间复杂度、稳定性以及代码示例:

1. 插入排序

  • 基本思想:每步将一个待排序的元素按其关键码值的大小插入到前面已经排序的部分中,直到全部插入完为止。
  • 时间复杂度:最坏和平均情况为O(n²),最佳情况为O(n)(当数据基本有序时)。
  • 稳定性:稳定的排序方法。
  • 代码示例
     
    public static void insertionSort(int[] array) {  
        int tmp;  
        for (int i = 1; i < array.length; i++) {  
            tmp = array[i];  
            int j = i;  
            for (; j > 0 && array[j - 1] > tmp; j--) {  
                array[j] = array[j - 1];  
            }  
            array[j] = tmp;  
        }  
    }

2. 冒泡排序

  • 基本思想:持续比较相邻的元素,如果第一个比第二个大,就交换它们,直到没有任何一对数字需要比较。
  • 时间复杂度:最坏和平均情况为O(n²),最佳情况为O(n)(当数据已经有序时)。
  • 稳定性:稳定的排序方法。
  • 代码示例
     
    public static void bubbleSort(int[] array) {  
        int tmp;  
        boolean flag;  
        for (int i = array.length - 1; i >= 0; i--) {  
            flag = false;  
            for (int j = 0; j < i; j++) {  
                if (array[j] > array[j + 1]) {  
                    tmp = array[j];  
                    array[j] = array[j + 1];  
                    array[j + 1] = tmp;  
                    flag = true;  
                }  
            }  
            if (!flag) break; // 如果没有发生交换,排序完成  
        }  
    }

3. 选择排序

  • 基本思想:每次从待排序的数据中选出最小(或最大)的元素,存放在序列的起始位置,直到全部排完。
  • 时间复杂度:O(n²)。
  • 稳定性:不稳定的排序方法。
  • 代码示例
     
    public static void selectSort(int[] array) {  
        for (int i = 0; i < array.length - 1; i++) {  
            int min = array[i];  
            int minindex = i;  
            for (int j = i; j < array.length; j++) {  
                if (array[j] < min) {  
                    min = array[j];  
                    minindex = j;  
                }  
            }  
            if (i != minindex) {  
                array[minindex] = array[i];  
                array[i] = min;  
            }  
        }  
    }

4. 希尔排序

  • 基本思想:先取一个小于n的整数作为增量,将数据分组并进行插入排序,逐步减小增量,直到增量为1时进行最后的插入排序。
  • 时间复杂度:依赖于增量序列,通常为O(n log n)到O(n²)之间。
  • 稳定性:不稳定的排序方法。
  • 代码示例
     
    public static void shellSort(int[] array) {  
        int n = array.length;  
        for (int gap = n / 2; gap > 0; gap /= 2) {  
            for (int i = gap; i < n; i++) {  
                int temp = array[i];  
                int j;  
                for (j = i; j >= gap && array[j - gap] > temp; j -= gap) {  
                    array[j] = array[j - gap];  
                }  
                array[j] = temp;  
            }  
        }  
    }

5. 归并排序

  • 基本思想:将数组分成两半,分别对两半进行排序,然后合并已排序的两半。
  • 时间复杂度:O(n log n)。
  • 稳定性:稳定的排序方法。
  • 代码示例
     
    public static void mergeSort(int[] array) {  
        if (array.length < 2) return;  
        int mid = array.length / 2;  
        int[] left = Arrays.copyOfRange(array, 0, mid);  
        int[] right = Arrays.copyOfRange(array, mid, array.length);  
        mergeSort(left);  
        mergeSort(right);  
        merge(array, left, right);  
    }  
    
    private static void merge(int[] array, int[] left, int[] right) {  
        int i = 0, j = 0, k = 0;  
        while (i < left.length && j < right.length) {  
            if (left[i] <= right[j]) {  
                array[k++] = left[i++];  
            } else {  
                array[k++] = right[j++];  
            }  
        }  
        while (i < left.length) array[k++] = left[i++];  
        while (j < right.length) array[k++] = right[j++];  
    }

6. 快速排序

  • 基本思想:选择一个基准元素,将数组分成两部分,左边部分小于基准,右边部分大于基准,然后递归排序这两部分。
  • 时间复杂度:最坏情况为O(n²),平均情况为O(n log n)。
  • 稳定性:不稳定的排序方法。
  • 代码示例
     
    public static void quickSort(int[] array, int low, int high) {  
        if (low < high) {  
            int pivotIndex = partition(array, low, high);  
            quickSort(array, low, pivotIndex - 1);  
            quickSort(array, pivotIndex + 1, high);  
        }  
    }  
    
    private static int partition(int[] array, int low, int high) {  
        int pivot = array[high];  
        int i = low - 1;  
        for (int j = low; j < high; j++) {  
            if (array[j] < pivot) {  
                i++;  
                int temp = array[i];  
                array[i] = array[j];  
                array[j] = temp;  
            }  
        }  
        int temp = array[i + 1];  
        array[i + 1] = array[high];  
        array[high] = temp;  
        return i + 1;  
    }

7. 堆排序

  • 基本思想:利用堆这种数据结构,首先构建一个最大堆,然后将堆顶元素与最后一个元素交换,缩小堆的大小并重新调整堆,直到排序完成。
  • 时间复杂度:O(n log n)。
  • 稳定性:不稳定的排序方法。
  • 代码示例
     
    public static void heapSort(int[] array) {  
        int n = array.length;  
        for (int i = n / 2 - 1; i >= 0; i--) {  
            heapify(array, n, i);  
        }  
        for (int i = n - 1; i > 0; i--) {  
            int temp = array[0];  
            array[0] = array[i];  
            array[i] = temp;  
            heapify(array, i, 0);  
        }  
    }  
    
    private static void heapify(int[] array, int n, int i) {  
        int largest = i;  
        int left = 2 * i + 1;  
        int right = 2 * i + 2;  
        if (left < n && array[left] > array[largest]) {  
            largest = left;  
        }  
        if (right < n && array[right] > array[largest]) {  
            largest = right;  
        }  
        if (largest != i) {  
            int swap = array[i];  
            array[i] = array[largest];  
            array[largest] = swap;  
            heapify(array, n, largest);  
        }  
    }

8. 计数排序

  • 基本思想:通过统计每个元素出现的次数,然后根据计数结果直接将元素放入正确的位置。
  • 时间复杂度:O(n + k),其中n是待排序元素的数量,k是元素值的范围。
  • 稳定性:稳定的排序方法。
  • 代码示例
    public static void countingSort(int[] array) {  
        int max = Arrays.stream(array).max().getAsInt();  
        int[] count = new int[max + 1];  
        for (int num : array) {  
            count[num]++;  
        }  
        int index = 0;  
        for (int i = 0; i < count.length; i++) {  
            while (count[i] > 0) {  
                array[index++] = i;  
                count[i]--;  
            }  
        }  
    }

这些排序算法各有特点,适用于不同的场景和数据规模。在实际应用中,选择合适的排序算法可以显著提高程序的效率。掌握这些算法对于编程和面试都非常重要。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第十一章 TypeScript模块和命名空间的介绍和使用

文章目录 一、模块1. 导出基础导出重新导出导出重命名 2. 导入基础导入导入重命名 3. 默认导出4. 模块化兼容exports import require()编译结果 二、命名空间1. 例子2. 命名空间3. 引入命名空间 三、模块和命名空间 一、模块 JavaScript 在 ES2015 中引入了模块的概念&#x…

【331】基于Springboot的“有光”摄影分享网站系统

“有光”摄影分享网站设计与实现 摘 要 自互联网的发展至今&#xff0c;其基础理论与技术都已完善&#xff0c;并积极参与了整个社会各个领域。它容许信息根据媒体传播&#xff0c;并和信息可视化工具一起为大家提供优质的服务。对于信息多头管理、差错率高、信息安全系数差、…

【GAMES101笔记速查——Lecture 18 Advanced Topics in Rendering】

目录 1 渲染前沿 1.1 有偏vs无偏 1.2 无偏光线传播方法&#xff08;Unbiased light transport methods&#xff09; 1.2.1 双向路径追踪&#xff08;Bidirectional path tracing&#xff0c;BDPT&#xff09; &#xff08;1&#xff09;双向路径追踪(BDPT)举例 1.2.2 Metr…

《等保测评新视角:安全与发展的双赢之道》

在数字化转型的浪潮中&#xff0c;企业面临的不仅是技术革新的挑战&#xff0c;更有信息安全的严峻考验。等保测评&#xff0c;作为国家网络安全等级保护的一项重要措施&#xff0c;不仅为企业的安全护航&#xff0c;更成为推动企业高质量发展的新引擎。本文将从全新的视角&…

中航资本:光伏股,集体涨停!千亿龙头,罕见封板!

今日早盘&#xff0c;A股放量走强&#xff0c;半日成交超越万亿元。北证50指数持续放量上攻&#xff0c;飙升逾8%&#xff0c;再创前史新高&#xff0c;创业板指大涨逾3%&#xff0c;克复2200点&#xff0c;上证指数站上3300点。 盘面上&#xff0c;BC电池、固态电池、房地产、…

迁移学习|ResNet18

一、导入库 二、设置随机种子 三、数据增强和数据加载 四、加载预训练模型 五、定义损失函数和优化器 六、学习率调度器 七、训练模型 八、可视化训练过程 九、总结 1. 常见优化器概述 1.1 随机梯度下降&#xff08;SGD: Stochastic Gradient Descent&#xff09; 简介&…

CentOS系统Nginx的安装部署

CentOS系统Nginx的安装部署 安装包准备 在服务器上准备好nginx的安装包 nginx安装包下载地址为&#xff1a;https://nginx.org/en/download.html 解压 tar -zxvf nginx-1.26.1.tar.gz执行命令安装 # 第一步 cd nginx-1.26.1# 第二步 ./configure# 第三步 make# 第四步 mak…

基于RabbitMQ,Redis,Redisson,RocketMQ四种技术实现订单延时关闭功能及其相关优缺点介绍(以12306为主题)

目录 1. 延迟关闭订单 1.1 订单延时关闭功能技术选型 1.1.1 定时任务 1.1.2 RabbitMQ 1.1.3 Redis 过期监听 1.1.4 Redisson 1.1.5 RocketMQ 1.2 RocketMQ订单延时关闭发送方实现 1.3 RocketMQ订单延时关闭的消费方实现 1. 延迟关闭订单 用户发起订单后&#xff0c;如…

校园表白墙源码修复版

此校园表白墙源码基于thinkphp&#xff0c;因为时代久远有不少bug&#xff0c;经本人修复已去除大部分bug&#xff0c;添加了美化元素。 https://pan.quark.cn/s/1f9b3564c84b https://pan.baidu.com/s/1bb9vu9VV2jJoo9-GF6W3xw?pwd7293 https://caiyun.139.com/m/i?2hoTc…

Etcd 可观测最佳实践

简介 Etcd 是一个高可用的分布式键值存储系统&#xff0c;它提供了一个可靠的、强一致性的存储服务&#xff0c;用于配置管理和服务发现。它最初由 CoreOS 开发&#xff0c;现在由 Cloud Native Computing Foundation (CNCF) 维护。Etcd 使用 Raft 算法来实现数据的一致性&…

AI运动抽取转3D动画

用的Wonder Studio&#xff0c;不免费哈&#xff0c;也不能试了&#xff0c;都要钱。只能看别人的经验。 网址https://wonderdynamics.com/ 先别激动&#xff0c;参考别人的评论 登录后&#xff08;google登录&#xff09;界面如下 收费情况 视频教程 https://www.youtube.co…

【记录】VSCode|自用设置项

文章目录 1 基础配置1.1 自动保存1.2 编辑区自动换行1.3 选项卡换行1.4 空格代替制表符1.5 开启滚轮缩放 2 进阶设置2.1 选项卡不自我覆盖2.2 选项卡限制宽度2.3 选项卡组限制高度2.4 字体设置2.5 字体加粗2.6 侧边栏2.7 沉浸式代码模式 Zen Mode2.8 设置 Zen 模式的选项卡组 3…

深入了解 kotlinx-datetime:配置与使用指南

深入了解 kotlinx-datetime&#xff1a;配置与使用指南 在Kotlin多平台开发中&#xff0c;处理日期和时间是常见的需求。kotlinx-datetime库提供了强大且简洁的API来帮助开发者应对这一挑战。本文将详细介绍如何配置kotlinx-datetime库&#xff0c;并通过生动的示例演示其核心…

远程:HTTP基本身份验证失败。提供的密码或令牌不正确,或者您的账户启用了两步验证,您必须使用个人访问令牌而不是密码。

问题描述&#xff1a; remote: HTTP Basic: Access denied. The provided password or token is incorrect or your account has 2FA enabled and you must use a personal access token insteadof a password. See http://gitlab.cnovit.com/help/topics/git/troubleshooting…

从 Hadoop 迁移到数据 Lakehouse 的架构师指南

从 Hadoop 到数据湖仓一体架构的演变代表了数据基础架构的重大飞跃。虽然 Hadoop 曾经以其强大的批处理能力统治着大数据领域&#xff0c;但如今的组织正在寻求更敏捷、更具成本效益和现代化的解决方案。尤其是当他们越来越多地开始实施 AI 计划时。根本没有办法让 Hadoop 为 A…

C++ 类与对象(中) 默认成员函数

我们知道在类中&#xff0c;有成员变量和成员函数&#xff0c;我们可以通过创造不同的成员函数来实现这个类不同的功能&#xff0c;如果我们创造一个类&#xff0c;却不实现它的成员函数会如何呢&#xff1f;这个就涉及到类中的默认成员函数的概念了。但在本文我们主要介绍以下…

【Dash】feffery_antd_components 按钮组件的应用

一、feffery_antd_componenet 中的 AntdFloatButton 和 AntdFloatButtonGroup AntdFloatButton 和 AntdFloatButtonGroup 是两个用于创建悬浮按钮和悬浮按钮组的组件。 AntdFloatButton 是单个悬浮按钮组件&#xff0c;它提供了多种属性来定义按钮的外观及行为。AntdFloatBut…

WebView渲染异常导致闪退解决方案

背景&#xff1a; App主页面使用了大量WebView容器(10个以上)显示图表信息&#xff0c;最新发现bugly上面出现一些关于浏览器Native Crash&#xff0c;如下&#xff1a; 经排查&#xff0c;是WebView渲染失败导致Crash&#xff0c;可以通过webView.loadUrl("chrome://cra…

Pycharm搭配miniConda(Anaconda的轻量版本)建立虚拟环境管理不同项目不同依赖

需求 pip安装的版本会在全局环境下生效,导致不用的项目使用的是同一套环境,容易出现别人的项目跑的好好的,到了自己电脑就不能跑的问题需求 1.不同的项目可以设置不同的环境,同时支持自动切换环境2.便捷,轻量化管理当前的环境 如果可以,最好有一个可视化的平台,anaconda倒是支…