排序算法基本原理及实现2

                                                                                             

                                   📑打牌 : da pai ge的个人主页
                                   🌤️个人专栏 : da pai ge的博客专栏
                                  ☁️宝剑锋从磨砺出,梅花香自苦寒来

🌤️冒泡排序

🌤️原理

在无序区间,通过相邻数的比较,将最大的数冒泡到无序区间的最后,持续这个过程,直到数组整体有序

private void swap(int[] array, int i, int j) {int t = array[i];array[i] = array[j];array[j] = t;}private void createHeap(int[] array) {for (int i = (array.length - 1) / 2; i >= 0; i--) {shiftDown(array, array.length, i);}}public static void shiftDown(int[] array, int size, int index) {int left = 2 * index + 1;while (left < size) {int max = left;int right = 2 * index + 2;if (right < size) {if (array[right] > array[left]) {max = right;}}if (array[index] >= array[max]) {break;}int t = array[index];array[index] = array[max];array[max] = t;index = max;left = 2 * index + 1;}}

时间复杂度

空间复杂度

最好O(n)

平均O(n^2)

最坏O(n^2)

数据有序数据逆序

🌤️实现

public static void bubbleSort(int[] array) {for (int i = 0; i < array.length - 1; i++) {boolean isSorted = true;for (int j = 0; j < array.length - i - 1; j++) {// 相等不交换,保证稳定性if (array[j] > array[j + 1]) {swap(array, j, j + 1);isSorted = false;}}if (isSorted) {break;}}}

🌤️快速排序

🌤️原理-总览

1. 从待排序区间选择一个数,作为基准值(pivot);

2. Partition: 遍历整个待排序区间,将比基准值小的(可以包含相等的)放到基准值的左边,将比基准值大的(可

以包含相等的)放到基准值的右边;

3. 采用分治思想,对左右两个小区间按照同样的方式处理,直到小区间的长度 == 1,代表已经有序,或者小区间

的长度 == 0,代表没有数据。

实现:

public static void quickSort(int[] array) {quickSortInternal(array, 0, array.length - 1);}// [left, right] 为待排序区间private static void quickSortInternal(int[] array, int left, int right) {if (left == right) {return;}if (left > right) {return;}// 最简单的选择基准值的方式,选择 array[left] 作为基准值// pivotIndex 代表基准值最终停留的下标int pivotIndex = partition(array, left, right);// [left, pivotIndex - 1] 都是小于等于基准值的// [pivotIndex + 1, right] 都是大于等于基准值的quickSortInternal(array, left, pivotIndex - 1);quickSortInternal(array, pivotIndex + 1, right);}

🌤️原理-partition

Hoare :

实现:

private static int partition(int[] array, int left, int right) {int i = left;int j = right;int pivot = array[left];while (i < j) {while (i < j && array[j] >= pivot) {j--;}while (i < j && array[i] <= pivot) {i++;}swap(array, i, j);}swap(array, i, left);return i;}挖坑

基本思路和Hoare 法一致,只是不再进行交换,而是进行赋值(填坑+挖坑)

实现:

前后遍历法:

private static int partition(int[] array, int left, int right) {int d = left + 1;int pivot = array[left];for (int i = left + 1; i <= right; i++) {if (array[i] < pivot) {swap(array, i, d);d++;}}swap(array, d, left);return d;}

🌤️性能分析

时间复杂度

空间复杂度

最好 平均O(n * log(n))

最坏 最好O(n * log(n))

平均 最坏O(n^2) O(log(n)) O(log(n)) O(n)

稳定性:不稳定

🌤️原理-基准值的选择

1. 选择边上(左或者右)

2. 随机选择

3. 几数取中(例如三数取中):array[left], array[mid], array[right] 大小是中间的为基准值

🌤️原理-非递归分治

public static void quickSort(int[] array) {Stack<Integer> stack = new Stack<>();stack.push(array.length - 1);stack.push(0);while (!stack.isEmpty()) {int left = stack.pop();int right = stack.pop();if (left >= right) {continue;}int pivotIndex = partition(array, left, right);stack.push(right);stack.push(pivotIndex + 1);stack.push(pivotIndex - 1);stack.push(left);}}

🌤️优化总结

1. 选择基准值很重要,通常使用几数取中法

2. partition 过程中把和基准值相等的数也选择出来

3. 待排序区间小于一个阈值时(例如 48),使用直接插入排序

🌤️总结

1. 在待排序区间选择一个基准值

1. 选择左边或者右边

2. 随机选取

3. 几数取中法

2. 做 partition,使得小的数在左,大的数在右

1. hoare

2. 挖坑

3. 前后遍历

4. 将基准值相等的也选择出来(了解)

3. 分治处理左右两个小区间,直到小区间数目小于一个阈值,使用插入排序

🌤️归并排序

🌤️原理-总览

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and

Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子

序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

🌤️原理-合并两个有序数组

private static void merge(int[] array, int low, int mid, int high) {int i = low;int j = mid;int length = high - low;int[] extra = new int[length];int k = 0;// 选择小的放入 extrawhile (i < mid && j < high) {// 加入等于,保证稳定性if (array[i] <= array[j]) {extra[k++] = array[i++];} else {extra[k++] = array[j++];}}// 将属于元素放入 extrawhile (i < mid) {extra[k++] = array[i++];}while (j < right) {extra[k++] = array[j++];}

时间复杂度

空间复杂度

O(n * log(n))

O(n)

数据不敏感

数据不敏感

// 从 extra 搬移回 arrayfor (int t = 0; t < length; t++) {// 需要搬移回原位置,从 low 开始array[low + t] = extra[t];}}

🌤️实现

public static void mergeSort(int[] array) {mergeSortInternal(array, 0, array.length);}// 待排序区间为 [low, high)private static void mergeSortInternal(int[] array, int low, int high) {if (low - 1 >= high) {return;}int mid = (low + high) / 2;mergeSortInternal(array, low, mid);mergeSortInternal(array, mid, high);merge(array, low, mid, high);}

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

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

相关文章

简单位运算

文章目录 求 n n n 的第 k k k 位是二进制的几lowbit(n)操作求解 n n n 的最后一个 1 1 1题目练习AcWing 801. 二进制中1的个数CODE1 原码、补码、反码 求 n n n 的第 k k k 位是二进制的几 我们需要用到&运算符&#xff1a;两位都为 1 1 1 时结果才为 1 1 1 &…

Linux小程序之进度条

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;自己能实现进度条 > 毒鸡汤&#xff1a; > …

制作心理咨询小程序的详细指南

随着科技的的发展&#xff0c;小程序已经成为了人们日常生活中不可或缺的一部分。特别是在心理咨询这个领域&#xff0c;小程序可以提供一个更为便捷、高效的服务平台。本文将通过乔拓云平台为例&#xff0c;详细介绍如何制作一个心理咨询小程序。 首先&#xff0c;我们需要注册…

【软件测试】盘一盘工作中遇到的 Redis 异常测试

在测试工作中&#xff0c;涉及到与 redis 交互的场景变的越来越多了。关于redis本身就不作赘述了&#xff0c;网上随便搜&#xff0c;本人也做过一些整理。 今天只来复盘一下&#xff0c;在测试过程中与 redis 的二三事儿。其中提到的案例是经过抽象化的&#xff0c;用作辅助说…

【SpringCloud系列】@FeignClient微服务轻舞者

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

基于Java web的多功能游戏大厅系统的开发与实现

摘 要 目前&#xff0c;国内游戏市场上的网络游戏有许多种类&#xff0c;游戏在玩法上也越来越雷同&#xff0c;形式越来越单调。这种游戏性系统给玩家带来的成就感虽然是无穷的&#xff0c;但是也有随之而来的疲惫感&#xff0c;尤其是需要花费大量的时间和精力&#xff0c;这…

Findreport中框架图使用的注意事项

目录 简介 测试数据 闭环链路关系 解决办法&#xff1a; 根不唯一 解决办法&#xff1a; 简介 在框架图的应用中&#xff0c;一些表达上下游关系的数据非常适合用于做链路图相关的报表。可以展示成雪花图&#xff0c;普通架构图。但是在实际操作中有几点关于数据的注意事…

【STM32】OLED显示屏

1 调试方式 1. 串口调试&#xff1a;通过串口通信&#xff0c;将调试信息发送到电脑端&#xff0c;电脑使用串口助手显示调试信息 2. 显示屏调试&#xff1a;直接将显示屏连接到单片机&#xff0c;将调试信息打印在显示屏上 3. Keil调试模式&#xff1a;借助Keil软件的调试模…

【精选】VulnHub red 超详细过程思路

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【java】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏 …

如何在代码中启动与关闭ROS节点

在ROS开发中&#xff0c;节点的管理是很重要的一部分&#xff0c;其中有一些节点大部分时候用不到&#xff0c;只会在特定情况下被启动&#xff08;比如建图节点&#xff09;同时这些节点在使用完后还需要被关闭&#xff0c;因此我们就需要在程序中对这些节点进行启动与关闭的管…

6 Redis缓存设计与性能优化

缓存穿透 缓存穿透是指查询一个根本不存在的数据&#xff0c; 缓存层和存储层都不会命中&#xff0c; 通常出于容错的考虑&#xff0c; 如果从存储层查不到数据则不写入缓存层。缓存穿透将导致不存在的数据每次请求都要到存储层去查询&#xff0c; 失去了缓存保护后端存储的意义…

从0开始学习JavaScript--JavaScript中的解构赋值及使用场景

在现代JavaScript中&#xff0c;解构赋值是一种强大而灵活的语法特性&#xff0c;它允许从数组或对象中提取值并赋给变量。这种语法不仅使代码更简洁&#xff0c;而且提高了可读性。在本篇文章中&#xff0c;将深入探讨JavaScript中解构赋值的基本概念、语法规则以及丰富的使用…

Python接口自动化测试如何设计接口测试用例(详解)

简介 上篇我们已经介绍了什么是接口测试和接口测试的意义。在开始接口测试之前&#xff0c;我们来想一下&#xff0c;如何进行接口测试的准备工作。或者说&#xff0c;接口测试的流程是什么&#xff1f;有些人就很好奇&#xff0c;接口测试要流程干嘛&#xff1f;不就是拿着接口…

亲子开衫外套 I 真的好温柔好有气质

分享适合宝宝和麻麻 一起穿的开衫外套 包芯纱拼貂毛 软糯亲肤不扎人 上身体验感非常不错 这种面料还不易起球 质感满满&#xff0c;单穿内搭都可&#xff01;

ChatGPT Plus/GPT4高级数据分析和插件功能详解

ChatGPT 在论文写作与编程方面也具备强大的能力。无论是进行代码生成、错误调试还是解决编程难题&#xff0c;ChatGPT都能为您提供实用且高质量的建议和指导&#xff0c;提高编程效率和准确性。此外&#xff0c;ChatGPT是一位出色的合作伙伴&#xff0c;可以为您提供论文写作的…

智能优化算法应用:基于鸟群算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于鸟群算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于鸟群算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.鸟群算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…

Python向Excel写入内容的方法大全

在数据处理和分析中&#xff0c;将Python中的数据写入Excel是一项常见任务。 本文将介绍几种常见的方法&#xff0c;以及如何使用它们向Excel中写入内容。 方法一&#xff1a;使用openpyxl库 openpyxl是一个功能强大的库&#xff0c;用于读写Excel文件。以下是一个简单的使用…

Java数据结构之优先级队列(PriorityQueue)

1、概念 队列&#xff1a;是一种FIFO&#xff08;First-In-First-Out&#xff09;先进先出的数据结构&#xff0c;对应于生活中的排队的场景&#xff0c; 排在前面的人总是先通过&#xff0c;依次进行。 优先队列&#xff1a;是特殊的队列&#xff0c;从“优先”一词&#xff…

第20章 多线程

创建线程 继承Thread 类 Thread 类时 java.lang 包中的一个类&#xff0c;从类中实例化的对象代表线程&#xff0c;程序员启动一个新线程需要建立 Thread 实例。 Thread 对象需要一个任务来执行&#xff0c;任务是指线程在启动时执行的工作&#xff0c;start() 方法启动线程&am…

系列十五、BeanDefinition

一、BeanDefinition 1.1、概述 BeanDefinition是一个接口&#xff0c;主要负责存储bean的定义信息&#xff0c;决定bean的生产方式&#xff0c;是一个定义态的bean&#xff0c;类似于说明书。后续BeanFactory就可以根据这些信息生产bean了。比如实例化&#xff1a;可以通过反射…