Java快速排序希尔排序归并排序

news2024/9/29 17:38:19
快速排序算法

在这里插入图片描述

快速排序的原理:选择一个关键值作为基准值。比基准值小的都在左边序列(一般是无序的),比基准值大的都在右边(一般是无序的)。一般选择序列的第一个元素。

一次循环:从后往前比较,用基准值和最后一个值比较,如果比基准值小的交换位置,如果没有继续比较下一个,直到找到第一个比基准值小的值才交换。找到这个值之后,又从前往后开始比较,如果有比基准值大的,交换位置,如果没有继续比较下一个,直到找到第一个比基准值大的值才交换。直到从前往后的比较索引>从后往前比较的索引,结束第一次循环,此时,对于基准值来说,左右两边就是有序的了。

public void sort(int[] a, int low, int high) {

        int start = low;

        int end = high;

        int key = a[low];

        while (end > start) {

            //从后往前比较

            while (end > start && a[end] >= key)

//如果没有比关键值小的,比较下一个,直到有比关键值小的交换位置,然后又从前往后比较

                end--;

            if (a[end] <= key) {

                int temp = a[end];

                a[end] = a[start];

                a[start] = temp;

            }

            //从前往后比较

            while (end > start && a[start] <= key)

//如果没有比关键值大的,比较下一个,直到有比关键值大的交换位置

                start++;

            if (a[start] >= key) {

                int temp = a[start];

                a[start] = a[end];

                a[end] = temp;

            }

            //此时第一次循环比较结束,关键值的位置已经确定了。左边的值都比关键值小,右边的

            值都比关键值大,但是两边的顺序还有可能是不一样的,进行下面的递归调用

        }

        //递归

        if (start > low) sort(a, low, start - 1);//左边序列。第一个索引位置到关键值索引-1

        if (end < high) sort(a, end + 1, high);//右边序列。从关键值索引+1 到最后一个

    }

}
希尔排序算法

基本思想:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。

  1. 操作方法:选择一个增量序列 t1,t2,…,tk,其中 ti>tj,tk=1;

  2. 按增量序列个数 k,对序列进行 k 趟排序;

  3. 每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

在这里插入图片描述

private void shellSort(int[] a) {

        int dk = a.length / 2;

        while (dk >= 1) {

            ShellInsertSort(a, dk);

            dk = dk / 2;

        }

    }

    private void ShellInsertSort(int[] a, int dk) {

//类似插入排序,只是插入排序增量是 1,这里增量是 dk,把 1 换成 dk 就可以了

        for (int i = dk; i < a.length; i++) {

            if (a[i] < a[i - dk]) {

                int j;

                int x = a[i];//x 为待插入元素

                a[i] = a[i - dk];

                for (j = i - dk; j >= 0 && x < a[j]; j = j - dk) {

//通过循环,逐个后移一位找到要插入的位置。

                    a[j + dk] = a[j];

                }

                a[j + dk] = x;//插入

            }

        }

    }
归并排序算法

image-20240107110801218

归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。

public class MergeSortTest {

        public static void main(String[] args) {

            int[] data = new int[]{5, 3, 6, 2, 1, 9, 4, 8, 7};

            print(data);

            mergeSort(data);

            System.out.println("排序后的数组:");

            print(data);

        }

        public static void mergeSort(int[] data) {

            sort(data, 0, data.length - 1);

        }

        public static void sort(int[] data, int left, int right) {

            if (left >= right)

                return;

            // 找出中间索引 

            int center = (left + right) / 2;

            // 对左边数组进行递归 

            sort(data, left, center);

            // 对右边数组进行递归 

            sort(data, center + 1, right);

            // 合并 

            merge(data, left, center, right);

            print(data);

        }

        /**
         * \* 将两个数组进行归并,归并前面 2 个数组已有序,归并后依然有序
         * <p>
         * \*
         * <p>
         * \* @param data
         * <p>
         * \* 数组对象
         * <p>
         * \* @param left
         * <p>
         * \* 左数组的第一个元素的索引
         * <p>
         * \* @param center
         * <p>
         * \* 左数组的最后一个元素的索引,center+1 是右数组第一个元素的索引
         * <p>
         * \* @param right
         * <p>
         * \* 右数组最后一个元素的索引
         */

        public static void merge(int[] data, int left, int center, int right) {

            // 临时数组 

            int[] tmpArr = new int[data.length];

            // 右数组第一个元素索引 

            int mid = center + 1;

            // third 记录临时数组的索引 

            int third = left;

            // 缓存左数组第一个元素的索引 

            int tmp = left;

            while (left <= center && mid <= right) {

                // 从两个数组中取出最小的放入临时数组 

                if (data[left] <= data[mid]) {

                    tmpArr[third++] = data[left++];

                } else {

                    tmpArr[third++] = data[mid++];

                }

            }

            // 剩余部分依次放入临时数组(实际上两个 while 只会执行其中一个) 

            while (mid <= right) {

                tmpArr[third++] = data[mid++];

            }

            while (left <= center) {

                tmpArr[third++] = data[left++];

            }

            // 将临时数组中的内容拷贝回原数组中 

            // (原 left-right 范围的内容被复制回原数组) 

            while (tmp <= right) {

                data[tmp] = tmpArr[tmp++];

            }

        }

        public static void print(int[] data) {

            for (int i = 0; i < data.length; i++) {

                System.out.print(data[i] + "\t");

            }

            System.out.println();

        }

    }

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

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

相关文章

软件测试|什么是Python构造方法,构造方法如何使用?

构造方法&#xff08;Constructor&#xff09;是面向对象编程中的重要概念&#xff0c;它在创建对象时用于初始化对象的实例变量。在Python中&#xff0c;构造方法是通过特殊的名称__init__()来定义的。本文将介绍Python构造方法的基本概念、语法和用法。 什么是构造方法&…

Qt添加资源文件

ui->setupUi(this);//1. 使用本地文件&#xff1a;ui->actionasdasdas->setIcon(QIcon("本地绝对路径"));ui->actiona1->setIcon(QIcon("C:/Users/满满/Desktop/output/picture/1.jpg"));//2. 使用资源文件&#xff1a;ui->actionasdasd…

二叉树基础oj练习(单值二叉树、相同的树、二叉树的前序遍历)

讲了这么多数据结构相关的知识(可以看我的数据结构文章专栏): 抓紧刷题巩固一下了 目录 1.单值二叉树 题目描述 思路1 代码1 思路2 代码2 2.相同的树 题目描述 思路 代码 3.二叉树的前序遍历 代码 思路 1.单值二叉树 965. 单值二叉树 - 力扣&#xff08;LeetCod…

NVM NodeJs版本管理 通关宝典

NVM NodeJs版本管理 通关宝典&#x1f3f9; 文章目录 NVM NodeJs版本管理 通关宝典&#x1f3f9;一、NVM是什么二、开始使用NVM三、NVM 命令速查四、手动安装特定Node版本(Windows)&#x1f644;4.1 NVM for windows 运行机制4.2 手动安装流程 五、切换 NVM 下载镜像源六、常见…

docker拉取镜像提示 remote trust data does not exist for xxxxxx

1、How can I be sure that I am pulling a trusted image from docker 2、docker: you are not authorized to perform this operation: server returned 401. 以上两个问题可以试试以下解决办法 DOCKER_CONTENT_TRUSTfalse 本人是使用jenkins部署自己的项目到docker容器出现…

【技巧】IDEA 使用小技巧(三)

IDEA 使用小技巧&#xff08;三&#xff09; 配置目录Ctrl 鼠标方法缩小字体 配置目录 IDEA 在使用的过程中会在 C 盘的用户目录下写入相关配置&#xff0c;目录如下&#xff1a; "C:\Users\个人用户名\AppData\Local\JetBrains" "C:\Users\个人用户名\AppDa…

在线制作假期承诺书,电子手写签名确认,一键导出打印。

假期将至&#xff0c;为积极落实安全管理规定&#xff0c;单位通常需要下发安全承诺书进行签字确认。 易查分可以实现网上下发安全承诺书通知&#xff0c;让查询者进行签名确认&#xff0c;还可以生成PDF&#xff0c;方便打印一人一张的纸质版承诺书&#xff0c;本次就来介绍如…

C#编程-实现函数重载

考虑一个示例&#xff1a;您必须编写一个程序来实现计算器的功能。计算器执行各种运算&#xff0c;例如数字的加、减及乘等。可以对任何类型的数据执行这些运算。这是否意味着您必须定义单独的函数名&#xff08;如addInteger、addFloat和addDoublie&#xff09;对每种此类数字…

扫码支付是怎么工作的?

扫码支付是怎么工作的&#xff1f; 本文转自 公众号 ByteByteGo&#xff0c;如有侵权&#xff0c;请联系&#xff0c;立即删除 过去的几十年&#xff0c;支付技术发生了很大的改变。下图给我们显示了 POS 终端的进化。从一开始的纸钞收银机&#xff0c;到刷卡机&#xff0c;再到…

Python 教程 02:Python 编程环境的搭建与 IDE 的选择

目录 一、搭建 Python 环境 1.1 Python 官网 1.2 下载 Python 1.2.1 选择版本 1.2.2 选择平台 1.2.3 下载安装文件&#xff08;Windows & macOS&#xff09; 1.3 安装环境 1.3.1 Windows 平台 1.3.2 macOS 平台 1.3.3 Linux 平台 1.4 验证安装是否成功 二、选择…

OpenHarmony应用构建工具Hvigor的构建流程

前言 OpenHarmony 应用和服务使用 Hvigor 作为工程的构建工具。本篇文章将介绍 Hvigor 的构建流程&#xff0c;通过修改脚本配置使 Hvigor 执行自定义任务。 Hvigor 的构建流程 加载命令行参数和环境变量&#xff1b;初始化项目结构&#xff0c;创建 Project 和 Module 实例…

计算机网络-VLAN原理与配置

之前我们学习了以太网的基础知识&#xff0c;了解了网络交换设备的发展&#xff0c;交换机的工作原理&#xff0c;广播域和冲突域。 一、概述 还简单了解了以太网的CSMA/CD通讯机制&#xff0c;以太网是建立在CSMA/CD (Carrier Sense Multiple Access/Collision Detection&…

C++ 学习笔记之运算符重载+案例

目录 一、C 运算符重载 二、定义一个成员函数或全局函数 三、计算时间 1.计算时间差 2.时间加减 四、一个运算符重载实例 一、C 运算符重载 是一种特性&#xff0c;它允许程序员重新定义已有的运算符的行为&#xff0c;以适应自定义类型的操作。通过运算符重载&#xff0…

java内存屏障

参考&#xff1a;https://blog.csdn.net/weixin_73077810/article/details/132804522 内存屏障主要用于解决线程的可见性、有序性问题 代码案例&#xff1a; ReentrantLock保证可见性的原理 在 lock.lock() 和 lock.unlock() 时&#xff0c;都会操作 AbstractQueuedSy…

UEditor在编辑对齐方式时产生额外空行问题

一、问题描述 一个关于UEditor富文本编辑器的问题&#xff1a;在编辑内容对齐方式后保存后浏览器显示的段落上下会比原先多出一些间距。 下面是对齐编辑后&#xff0c;未保存前的的HTML&#xff1a; 保存后&#xff0c;实际会多出一个段落空行&#xff1a; 二、问题调查 经…

Java多线程技术11——ThreadPoolExecutor类的使用1-备份

1 概述 ThreadPoolExecutor类可以非常方便的创建线程池对象&#xff0c;而不需要程序员设计大量的new实例化Thread相关的代码。 2 队列LinkedBlockingQueue的使用 public class Test1 {public static void main(String[] args) {LinkedBlockingQueue queue new LinkedBlocki…

字节跳动基础架构SRE-Copilot获得2023 CCF国际AIOps挑战赛冠军

近日&#xff0c;2023 CCF国际AIOps挑战赛决赛暨“大模型时代的AIOps”研讨会在北京成功举办&#xff0c;活动吸引了来自互联网、运营商、科研院所、高校、软硬件厂商等领域多名专家学者参与&#xff0c;为智能运维的前沿学术研究、落地生产实践打开了新思路。决赛中&#xff0…

leetcode算法题之记忆化搜索总结

记忆化搜索&#xff0c;可以理解为带备忘录的递归&#xff0c;方便进行剪枝&#xff0c;是一种以空间换时间的策略。 本章目录 1.斐波那契数2.不同路径3.最长递增子序列4.猜数字大小II5.矩阵中的最长递增路径 1.斐波那契数 斐波那契数 class Solution { public://递归int f…

GitEE-GitHub实现加速访问与下载项目

gitee域名&#xff1a;https://gitee.com gitee域名&#xff1a;https://github.com 一、从github导出项目到gitee上面&#xff0c;从而实现加速访问与下载 gitee和github都有同步其他仓库的功能&#xff0c;比如码云上就能直接从github或gitlab中导入&#xff1b; 只需要填…

路由器02_静态路由DHCP

一、静态路由 &#xff11;、静态路由特点 由管理员手工配置&#xff0c;是单向的&#xff0c;缺乏灵活性 &#xff12;、默认路由 默认路由是一种比较特殊静态路由&#xff0c;一般用于末节&#xff08;末梢&#xff09;网络&#xff0c;直接指定目标为任何地方 二、静态…