插入、希尔、归并、快速排序(java实现)

news2025/1/11 14:11:59

目录

插入排序

希尔排序

归并排序

快速排序


插入排序

排序原理:

1.把所有元素分为两组,第一组是有序已经排好的,第二组是乱序未排序。

2.将未排序一组的第一个元素作为插入元素,倒序与有序组比较。

3.在有序组中找到比插入元素小或者大的元素,将插入元素放入该位置,后面元素向后移动一位。

 时间复杂度:O(n^2)

稳定性:当A与B相等,排序前A若在B前,排序后A仍然在B前,就说明该排序是稳定的。

插入排序:稳定

//比较两元素大小方法
    private static boolean greater(Comparable v,Comparable w){
        return v.compareTo(w)>0;
    }
 //数组中 交换元素位置
    private static void exch(Comparable[] a,int i,int j){
        Comparable temp;
        temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }

插入排序

    public static void insertSort(Comparable[] a){
        for (int i = 1; i < a.length-1; i++) {
            for (int j = i+1; j >0; j--) {
                if (greater(a[j-1],a[j])){
                    exch(a,j-1,j);
                }else break;
            }
        }
    }

希尔排序

排序原理:

1.选择一个增长量h,按照h将数据分组。

2.每组进行插入排序。

3.减少增长量h直到h=1,重复步骤2

稳定性:不稳定

     public static void shellSort(Comparable[] a){
        int h = 1;
        //确定h
        while (h<a.length/2){
            h = 2*h+1;
        }
        // 希尔排序
        while (h>=1){
            for (int i = h; i < a.length; i=i+h) {
                for (int j = i; j >= h; j=j-h) {
                    if (greater(a[j-h],a[j])){
                        exch(a,j-h,j);
                    }else break;
                }
            }
            h=h/2;
        }
    }

归并排序

排序原理:

1.尽可能的一组数据拆分成两个元素相等的子组,并对每一个子组继续拆分,直到拆分后的每个子

组的元素个数是1为止。

2.将相邻的两个子组进行合并成一个有序的大组;

3.不断的重复步骤2,直到最终只有一个组为止。

时间复杂度:O(nlogn)

稳定性: 稳定

import java.util.Arrays;

public class Merge {
    //归并需要的辅助数组
    private static Comparable[] assist;

    //判断v是否比w小
    private static boolean less(Comparable v,Comparable w){
        return v.compareTo(w)<0;
    }
    //交换元素
    private static void exch(Comparable[] a,int i,int j){
        Comparable t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
    //对数组a排序
    public static void sort(Comparable[] a){
        //    1.初始化辅助数组assist
        assist= new Comparable[a.length];
        //    定义lo变量和hi变量。分别记录数组中最小的索引和最大的索引
        int lo = 0;
        int hi = a.length-1;
        sort(a,lo,hi);
    }
    //对数组a中从lo到hi元素进行排序
    private static void sort(Comparable[] a,int lo,int hi){
    //安全检验
        if (hi<=lo){
            return;
        }
    //  对lo和hi之间的数据进行分为两组
        int mid = lo+(hi-lo)/2;
    //    分别排序
        sort(a,lo,mid);
        sort(a,mid+1,hi);
    //两组归并
        merge(a,lo,mid,hi);
    }

    //归并
    private static void merge(Comparable[] a,int lo,int mid,int hi){
    //    定义三个指针
        int i = lo;
        int p1 = lo;
        int p2 = mid+1;
    //    遍历移动p1指针和p2指针,比较对应 索引处的值,找出小的,放到辅助数组对应分索引处
       while (p1<=mid&&p2<=hi){
           if (less(a[p1],a[p2])){
               assist[i++] = a[p1++];
           }else {
               assist[i++] = a[p2++];
           }
       }
    //遍历,如果p1的指针没有走完,将p1剩余遍历到辅助数组中
        while (p1<=mid){
            assist[i++] = a[p1++];
        }
    //遍历,如果p2的指针没有走完,将p2剩余遍历到辅助数组中
        while (p2<=hi){
            assist[i++] = a[p2++];
        }
    //    把辅助数组中的元素复制到原数组中
        for (int index = lo;index<=hi;index++){
            a[index] = assist[index];
        }
    }

    public static void main(String[] args) {
        Integer[] a={7,8,4,5,6,1,3,9,2};
        Merge.sort(a);
        System.out.println(Arrays.toString(a));
    //    [1, 2, 3, 4, 5, 6, 7, 8, 9]
    }

}

快速排序

排序原理:
1.首先设定一个分界值,通过该分界值将数组分成左右两部分;

2.将大于或等于分界值的数据放到到数组右边,小于分界值的数据放到数组的左边。此时左边部分

中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值;

3.然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分

数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处

理。
4.重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧

部分的顺序。当左侧和右侧两个部分的数据排完序后,整个数组的排序也就完成了。 

时间复杂度:

平均情况:O(nlogn),最坏情况:O(n^2) 

稳定性:不稳定 

import java.util.Arrays;

public class Quick {
    private static void exch(Comparable[] a,int i,int j){
        Comparable t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
    private static boolean less(Comparable v,Comparable w){
        return v.compareTo(w)<0;
    }
    //对数组内的元素进行排序
    public static void sort(Comparable[] a){
        int lo = 0;
        int hi = a.length-1;
        sort(a,lo,hi);
    }
    //对数组a中从索引hi之间的元素进行排序
    public static void sort(Comparable[] a,int lo,int hi){
        if (lo>=hi)return;
        int partition = partition(a,lo,hi);
        sort(a,lo,partition-1);
        sort(a,partition+1,hi);
    }

    private static int partition(Comparable[] a,int lo,int hi){
        //确定分界值
        Comparable key = a[lo];
        //定义两个指针,分别指向待切分元素的最小索引处和最大索引处的下一个位置
        int left = lo;
        int right = hi+1;
        //切分 扫描
        while (true){
            //先从右边向左扫描,移动right指针,找到比分界值小的,停止
            while (less(key,a[--right])){
                if (right==lo){
                    break;
                }
            }
            //从左边向右扫描,移动light指针,找到比分界值大的,停止
            while (less(a[++left],key)){
                if (left==hi){
                    break;
                }
            }
            //right<right时交换
            if (left>=right){
                break;
            }else {
                exch(a,left,right);
            }
        }
        //交换分界值
        exch(a,lo,right);
        return right;
    }

    public static void main(String[] args) {
        Integer a[] = {3,6,9,2,5,8,4,7,1};
        Quick.sort(a);
        System.out.println(Arrays.toString(a));
    //    [1, 2, 3, 4, 5, 6, 7, 8, 9]
    }

}

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

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

相关文章

大语言模型之一 Attention is all you need ---Transformer

大语言模型已经在很多领域大显身手&#xff0c;其应用包括只能写作、音乐创作、知识问答、聊天、客服、广告文案、论文、新闻、小说创作、润色、会议/文章摘要等等领域。在商业上模型即产品、服务即产品、插件即产品&#xff0c;任何形态的用户可触及的都可以是产品&#xff0c…

面试题:ArrayList扩容时扩容多少?

大家好&#xff0c;我是你们的小米&#xff01;今天要和大家一起来探讨一个在Java面试中经常被问到的问题&#xff1a;“ArrayList扩容时扩容多少&#xff1f;”相信很多小伙伴都在面试中遇到过这个问题&#xff0c;那么接下来&#xff0c;我就为大家详细解析一下这个问题&…

Vue3+Ts+Vite项目全局配置Element-Plus主题色

概述 我找了很多博客&#xff0c;想全局配置Elmenet-Plus组件主题色&#xff0c;但都没有效果。所以有了这篇博客&#xff0c;希望能对你有所帮助&#xff01;&#xff01;&#xff01; 文章目录 概述一、先看效果二、创建全局颜色文件2.1 /src/styles 下新建 element-plus.sc…

C#应用处理传入参数 - 开源研究系列文章

今天介绍关于C#的程序传入参数的处理例子。 程序的传入参数应用比较普遍&#xff0c;特别是一个随操作系统启动的程序&#xff0c;需要设置程序启动的时候不显示主窗体&#xff0c;而是在后台运行&#xff0c;于是就有了传入参数问题&#xff0c;比如传入/h或者/min等等。所以此…

湘大 XTU OJ 1260 Completed String 题解(非常详细):建立数组下标和数组元素之间的映射关系 ~scanf

一、链接 1260 Completed String 二、题目 题目描述 给一个字符串&#xff0c;请判断字符串是否出现了所有的英文字母&#xff08;不区分大小写&#xff09;。 输入 每行一个只含英文字母的字符串&#xff0c;长度不超过1000。 输出 每行输出一个样例的结果&#xff0c…

SpringBoot案例-部门管理-新增

根据页面原型&#xff0c;明确需求 页面原型 需求 阅读接口文档 接口文档链接如下&#xff1a; 【腾讯文档】SpringBoot案例所需文档 https://docs.qq.com/doc/DUkRiTWVaUmFVck9N 思路分析 前端在输入要新增的部门名称后&#xff0c;会以JSON格式将数据传入至后端&#xf…

基于Python实现的有限元方程求解程序附源码

问题描述 根据已知下列非齐次两点边值问题(1.2.28) { L u − d d x ( p d u d x ) q u f , a < x < b , u ( a ) α , u ′ ( b ) β , \begin{cases} \boldsymbol{L} u-\frac{\mathrm{d}}{\mathrm{d} x}\left(p \frac{\mathrm{d} u}{\mathrm{~d} x}\right)q uf, a…

markdown命令模板

markdown快速入门(typora) 1、代码块 //代码块语 public static void main(String[] args){}//linux下spring项目的启动命令 # java -jar blog start ## 2、标题&#xff1a;java # 一级标题 ## 二级标题 ### 三级标题 #### 四级标题 ##### 五级标题 ###### 六级标题3、字体 …

STM32 LL库+STM32CubeMX--点亮板载LED

一、前期准备 硬件&#xff1a;STM32F103C8T6开发板调试工具&#xff1a;DAPLink(本次使用)或USB-TTL开发环境&#xff1a;STM32CubeMX、Keil、Vscode(可选)板载LED&#xff1a;PC13(低电平点亮) 二、STM32CubeMX配置 1.选择芯片型号&#xff1a; 2.配置外设时钟&#xff1a…

步入React正殿 - 事件处理

目录 扩展学习资料 React事件和DOM事件 和传统DOM事件处理异同 this关键字的处理 this关键字 在JSX中使用bind方法 在构造函数中使用bind方法 使用箭头函数【推荐】 向事件处理程序传递参数【不跨组件】 向父组件传递参数 /src/App.js /src/components/listItem.jsx…

【MySQL--->数据库基础】

文章目录 [TOC](文章目录) 一、基本概念二、实际应用中的数据库三、mysql的架构四、mysql语句分类五、存储引擎查看 一、基本概念 mysql本质是一个CS模式的网络服务,mysql是客户端,mysqld是服务端,提供高效的数据存取方案.数据库系统简单来说是一个数据集合加上管理这个数据集…

Java旋转数组中的最小数字(图文详解版)

目录 1.题目描述 2.题解 分析 具体实现 方法一&#xff08;遍历&#xff09;&#xff1a; 方法二&#xff08;排序&#xff09;&#xff1a; 方法三&#xff08;二分查找&#xff09;&#xff1a; 1.题目描述 有一个长度为 n 的非降序数组&#xff0c;比如[1,2,3,4,5]&a…

【LeetCode 75】第二十六题(394)字符串解码

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码运行结果&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 给我们字符串&#xff0c;让我们解码&#xff0c;那么该怎么解码呢&#xff0c;被括号【】包裹起来的字符串需要扩展成括号左边第…

一百五十一、Kettle——Linux上安装的kettle8.2开启carte服务以及配置子服务器

一、目的 kettle8.2在Linux上安装好可以启动界面、并且可以连接MySQL、Hive、ClickHouse等数据库后&#xff0c;准备在Linux上启动kettle的carte服务 二、实施步骤 &#xff08;一&#xff09;carte服务文件路径 kettle的Linux运行的carte服务文件是carte.sh &#xff08;二…

grafana部署

一、前言 grafana是一款用于将prometheus收集的数据通过ui展示出来的组件&#xff0c;可以直观的看到每个数据的情况和指标&#xff0c;grafana有很多的ui展示模板可以使用 二、部署 这里我使用docker部署 先查找一下镜像 docker search grafana 创建存放grafana数据的目录…

C++初阶之一篇文章教会你list(理解和使用)

list&#xff08;理解和使用&#xff09; 什么是list特点和优势基本操作示例用法与其他序列式容器&#xff08;如 std::vector 和 std::deque&#xff09;相比&#xff0c;std::list 显著的区别和优势成员类型 list构造函数1. default (1)2. fill (2)3.range (3)4. copy (4) li…

无涯教程-Perl - opendir函数

描述 此函数使用readdir函数打开目录EXPR,并将其与DIRHANDLE关联以进行处理。 语法 以下是此函数的简单语法- opendir DIRHANDLE, EXPR返回值 如果成功,此函数将返回true。 例 以下是显示其基本用法的示例代码- #!/usr/bin/perl -w$dirname"/tmp";opendir ( …

MySQL~事务的四大特性和隔离级别

事务的四大特性 1.原子性&#xff1a;一个事务&#xff08;transaction&#xff09;中的所有操作&#xff0c;要么全部完成&#xff0c;要么全部不完成。事务在执行过程中发生错误&#xff0c;会被回滚&#xff08;Rollback&#xff09;到事务开始前的状态&#xff0c;就像这个…

MySQL环境与配置

安装MySQL https://www.mysql.com/ 进入下载官网后 下载完成后运行安装包下载完成后运行安装包 选择完路径后一直点下一步 然后运行MySQL 设置密码 这里如安装失败请右键我的电脑点击属性&#xff0c;检查电脑名和组名是否为英文 启动与停止MySQL mysql安装完毕后默认是运行…

【C语言】进阶指针,超详解,含丰富代码示例

文章目录 前言指针进阶的重点内容1.字符指针2.数组指针3.指针数组4.函数指针5.函数指针数组6. 指向函数指针数组的指针 总结 这里是初阶的链接&#xff0c;方便大家对照查看&#xff01;&#xff01;&#xff01;添加链接描述 前言 大家好呀&#xff0c;今天和大家将指针进阶…