66-插入排序

目录

1.直接插入排序

2.折半插入排序

3.在数组arr[l...r]上使用插入排序


类似打扑克牌,整理牌的时候,都是把乱的牌向已经码好的牌中插入——天然的插入排序。

1.直接插入排序

每次选择无序区间的第一个元素,插入到有序区间的合适位置,不断重复此流程,直到整个数组有序。整个区间被分为有序区间[0, i)和无序区间[i, n)。

 /**
  * 直接插入排序 稳定的
  * 每次选择无序区间的第一个元素,插入到有序区间的合适位置
  * @param arr
  */
public static void insertionSortBase(int[] arr) {
    //有序区间[0,i) [0,1)
    //默认第一个元素就是有序
    for (int i = 1; i < arr.length; i++) {
        //每次选择无序区间的第一个元素,插入到有序区间的合适位置
        //无序区间[i, n)
        for (int j = i; j > 0 && arr[j] < arr[j - 1]; j--) {
            swap(arr, j, j-1);
            //arr[j] > arr[j - 1]此时循环直接终止
            //arr[j - 1]已经是有序区间元素,大于前面的所有值
        }
    }
}

稳定性:稳定。

arr[j] > arr[j - 1]循环就终止了,因此相等元素排序前和排序后的次序不会发生变化。

性能:

时间复杂度:n * 1 + (n - 1) * 2 + (n - 2) * 3 + ... + 2 * (n - 1) + 1 * n => O(n ^ 2)

插入排序和选择排序最大的不同在于:若arr[j] >= arr[j - 1],循环可以直接终止,arr[j - 1]已经是有序区间元素。

插入排序在小数据规模上,在近乎有序的数组中,性能非常好。经常作为高级排序算法的优化手段。

2.折半插入排序

在有序区间选择数据应该插入的位置时,因为区间的有序性,可以利用折半查找(二分查找)的思想快速定位插入的位置。

/**
 * 折半插入排序
 * @param arr
 */
public static void insertionSortBS(int[] arr) {
    for (int i = 1; i < arr.length; i++) {
        //无序区间第一个值
        int val = arr[i];
        //有序区间[0,i)
        int low = 0;
        int high = i;
        while(low < high) {
            int mid = (low + high) >> 1;
            //将相等的值放在左半区间,保证稳定性
            if(val >= arr[mid]) {
                low = mid + 1;
            }else{
                //右区间取不到,不用 -1
                high = mid;
            }
        }
        //数据搬移
        for (int j = i; j > low; j--) {
            arr[j] = arr[j - 1];
        }
        //low就是元素插入位置
        arr[low] = val;
    }
}

稳定性:稳定。

时间复杂度:n * logn + n * (1...n) => O(N ^ 2)

折半插入排序(一个个比较交换,O(logn))比直接插入排序(找到插入位置后元素的搬移,O(n))主要快在查找(有序区间查找)上。

搬移次数 == 交换次数(因为最终插入位置是一样的)。

3.在数组arr[l...r]上使用插入排序

/**
 * 在数组arr[l...r]上使用插入排序
 * @param arr
 * @param l
 * @param r
 */
private static void insertBase(int[] arr, int l, int r) {
    //有序的区间[l...i]
    //无序的区间[i...r]
    for (int i = l + 1; i <= r; i++) {
        for (int j = i; j > l && arr[j] < arr[j - 1]; j--) {
            swap(arr, j, j - 1);
        }
    }
}

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

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

相关文章

chatGPT中国入口-ChatGPT评论文章-ChatGPT怎么用

国内怎么玩chatGPT 如果您在国内使用ChatGPT&#xff0c;主要的问题可能是连接OpenAI服务器的速度和稳定性。由于OpenAI位于美国&#xff0c;可能受到中国的网络限制和防火墙的影响&#xff0c;造成访问速度比较慢或不稳定。为了解决这个问题&#xff0c;您可以采取以下方法&a…

idea常用快捷键,包的介绍,访问修饰符

这里有的是我自己定义的快捷键&#xff0c;可以到图片是指定位置查看对应的快捷键是什么。删除当前行&#xff0c;Ctrld复制当前行&#xff0c;自己配置CtrlShift向下箭头补全代码 alt /注释Ctrl /自动导入包在上面位置把两个选项选中&#xff0c;在要导入包的红色位置输入al…

(C++)模板分离编译面对的问题

什么是分离编译模板的分离编译什么是分离编译 一个程序&#xff08;项目&#xff09;由若干个源文件共同实现&#xff0c;而每个源文件单独编译生成目标文件&#xff0c;最后将所有目标文件链接起来形成单一的可执行文件的过程称为分离编译模式。 模板的分离编译 假如有以下…

Spring入门(万字详细附代码讲解)

1.Spring介绍 Spring其实就是一种开源框架,指的是Spring Framework,具有良好的生态,这也是Spring经久不衰的原因 用一句话概括,Spring就是一个集成了众多工具和方法的IOC容器 2.IOC容器 什么是IOC容器呢? IOC的中文翻译过来就是控制反转,IOC容器其实就是控制反转容器 那什…

2022蓝桥杯省赛——卡片

问题描述 小蓝有 k 种卡片, 一个班有 n 位同学, 小蓝给每位同学发了两张卡片, 一位同学的两张卡片可能是同一种, 也可能是不同种, 两张卡片没有顺序。没有两位同学的卡片都是一样的。 给定 n, 请问小蓝的卡片至少有多少种? 输入格式 输入一行包含一个正整数表示 n 。 输出…

Vue中的slot插槽

目录 &#xff08;一&#xff09;什么是slot插槽 (1)slot插槽的作用 (2)插槽的好处和使用场景 &#xff08;3&#xff09;slot插槽的分类 1、默认插槽 2、具名插槽 3、作用域插槽 &#xff08;一&#xff09;什么是slot插槽 (1)slot插槽的作用 slot具有“占坑”的作用…

Hadoop MapReduce各阶段执行过程以及Python代码实现简单的WordCount程序

视频资料&#xff1a;黑马程序员大数据Hadoop入门视频教程&#xff0c;适合零基础自学的大数据Hadoop教程 文章目录Map阶段执行过程Reduce阶段执行过程Python代码实现MapReduce的WordCount实例mapper.pyreducer.py在Hadoop HDFS文件系统中运行Map阶段执行过程 把输入目录下文件…

【GoF 23 概念理解】AOP面向切面编程

1. 什么是AOP——面向切面编程 AOP是一种编程范式&#xff0c;提供了一种从宁一个角度来考虑程序结构以完善面向对象编程&#xff08;OOP&#xff09; AOP是一个思想上的变化——主从换位&#xff0c;让原本主动调用的模块变成了被动等待&#xff0c;甚至在毫不知情的情况下被…

CodeTON Round 4 (Div. 1 + Div. 2, Rated, Prizes!)A~E

比赛连接&#xff1a;Dashboard - CodeTON Round 4 (Div. 1 Div. 2, Rated, Prizes!) - Codeforces A. Beautiful Sequence 题意&#xff1a; t(1≤t≤500)组测试每组给定大小为n(1≤n≤100) 的序列&#xff0c;判断它是否存在一个子序列是好序列。一个序列是好序列当且仅当至…

GPT-3:大语言模型小样本学习

论文标题&#xff1a;Language Models are Few-Shot Learners论文链接&#xff1a;https://arxiv.org/abs/2005.14165论文来源&#xff1a;OpenAI一、概述自然语言处理已经从学习特定任务的表示和设计特定任务的架构转变为使用任务无关的预训练和任务无关的架构。这种转变导致了…

Python - Huffman Tree 霍夫曼树实现与应用

目录 一.引言 二.Huffman Tree 理论 1.定义 2.结构 3.构造 三.Huffman Tree 实现 1.生成霍夫曼树 2.编码霍夫曼编码 3.解码霍夫曼编码 4.霍夫曼树编码解码实践 四.总结 一.引言 上篇 Word2vec 的文章中指出每次计算词库 N 个单词的 Softmax 计算量很大&#xff0c;…

办公工具-latex

一、排版总论 1.1 缺省权力 ​ 首先&#xff0c;最重要最需要强调的是&#xff0c;排版是一个信息量极大的工程。字体&#xff0c;格式&#xff0c;对齐方式&#xff0c;页眉页脚&#xff0c;都只是排版的冰山一角&#xff0c;可以说&#xff0c;一个人是没有办法完全控制一个…

JVM 运行时数据区概述及线程

当我们通过前面的&#xff1a;类的加载 --> 验证 --> 准备 --> 解析 --> 初始化&#xff0c;这几个阶段完成后&#xff0c;就会用到执行引擎对我们的类进行使用&#xff0c;同时执行引擎将会使用到我们运行时数据区。 运行时数据区结构 内存概念&#xff1a; 内存…

leetcode:只出现一次的数字 Ⅲ(详解)

前言&#xff1a;内容包括&#xff1a;题目&#xff0c;代码实现&#xff0c;大致思路&#xff0c;代码解读 题目&#xff1a; 给你一个整数数组 nums&#xff0c;其中恰好有两个元素只出现一次&#xff0c;其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任…

Qt界面编程(三)—— 父子关系、对象树、信号和槽(自定义信号和槽、Qt5与Qt4的写法)

一、Qt按钮小程序 1. 按钮的创建和父子关系 在Qt程序中&#xff0c;最常用的控件之一就是按钮了&#xff0c;首先我们来看下如何创建一个按钮&#xff1a; #include <QPushButton>QPushButton * btn new QPushButton; //设置父亲btn->setParent(this);//设置文字b…

接口测试-postman使用总结

一、为何使用postman postman是一款简单高效的接口测试工具&#xff0c;能够很方便发送接口请求&#xff0c;易于保存接口请求脚本&#xff0c;postman提供接口响应数据比对功能&#xff0c;可以设置预期结果作断言&#xff0c;还能把测试用例放在一个集合中批量执行&#xff…

【JavaWeb】9—监听器

⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记链接&#x1f449;https://github.com/A-BigTree/Code_Learning ⭐⭐⭐⭐⭐⭐ 如果可以&#xff0c;麻烦各位看官顺手点个star~&#x1f60a; 如果文章对你有所帮助&#xff0c;可以点赞&#x1f44d;…

torchvision.transforms 常用方法解析(含图例代码以及参数解释)

本文代码和图片完全源于 官方文档: TRANSFORMING AND AUGMENTING IMAGES 中的 Illustration of transforms&#xff0c;参数介绍源自函数对应的官方文档。 代码中的变换仅仅使用了最简单的参数&#xff1a;pad&#xff0c;size 等&#xff0c;这里展现的只是简单的变换&#xf…

C/C++每日一练(20230408)

目录 1. 删除无效的括号 &#x1f31f;&#x1f31f;&#x1f31f; 2. 合并K个升序链表 &#x1f31f;&#x1f31f;&#x1f31f; 3. 四数之和 &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 …

SQL Server用户定义的函数(UDF)使用详解

SQL Server用户定义的函数一、背景知识1.1、用户定义函数的优点1.2、函数类型1.3、指引1.4、函数中的有效语句1.5、架构绑定函数1.6、指定参数二、创建用户定义函数2.1、限制和权限2.2、标量函数示例&#xff08;标量 UDF&#xff09;2.3、表值函数示例2.3.1、内联表值函数 &am…