数据结构之排序了如指掌(二)

目录

题外话

正题

选择排序

选择排序思路

选择排序代码详解

选择排序复杂度

双向选择排序

双向选择排序思路

双向选择排序代码详解

堆排序

堆排序思路

堆排序代码详解

堆排序复杂度

冒泡排序

冒泡排序思路

冒泡排序代码详解

冒泡排序复杂度

小结


题外话

今天状态超级好,废话不说直接写博客!!

先说下,我会尽力将博客中的各种问题,通过文字和图形和代码结合的方式让大家更直观清晰的去理解,毕竟写博客不是看视频,我只能尽量让大家明白这些知识

想学的人自然会去琢磨,不想学的人你就喂到他嘴里,他都不想咀嚼一下

正题

上篇我们写完了直接插入排序和希尔排序,让我们继续写排序内容

选择排序

选择排序思路

创建i和j

i从0下标开始,j从i+1开始

j在数组中寻找剩余元素的最小值

找到之后把最小值和i交换

循环此过程,直到i走到数组倒数第1个元素结束,倒数第一个元素不需要再排序,因为前面都排序完成,最后一个肯定是有序的

觉得上面讲的不清晰可以看下图

选择排序代码详解

public void selectSort(int[] arr)
{
    //创建tmp作为临时变量,swap作为交换变量
    int tmp;
    int swap;

    //i从0下标开始,i走到倒数第二个元素排完序就结束,最后一个元素必然有序!!
    for (int i=0;i<arr.length-1;i++) {
        //tmp是记录最小元素下标值,先将i下标放入tmp中
        tmp=i;

        //j下标就等于i+1
        int j = i + 1;

        //j每趟肯定是从i+1开始到数组最后一个元素结束
        for (; j <arr.length; j++) {

            //当tmp中元素大于j中元素,就说明tmp不是剩余数组中最小的元素
            if (arr[tmp] > arr[j]) {
                //将j下标传给tmp
                tmp = j;
            }
        }
        //如果i==tmp说明i此时就是剩余数组元素中最小的,不需要再交换位置
        //否则再交换位置
        if(i!=tmp)
        {
            swap = arr[tmp];
            arr[tmp] = arr[i];
            arr[i] = swap;
        }
    }
}

选择排序复杂度

时间复杂度:O(n^2)无论数组是否有序,i都会从0下标开始到arr.length-2下标结束

j总共会走n-1,n-2,n-3,.......1,相当于等差数列,所以计算出来为O(n^2)

空间复杂度:O(1),因为就一个数组

稳定性:不稳定,相同元素的位置可能会改变

双向选择排序

上面属于是单向的选择排序,下面我们说说另一个版本双向选择排序

双向选择排序思路

1.创建left,right两个变量,让left从0下标开始向后面走,让right从arr.lenght-1开始向前面走

2.创建minIndex,和maxIndex两个变量,并把left下标传给这两个变量

3.i从letf+1下标往后走,如果遇到比minIndex小的下标元素,就把i下标传给minIndex

4.如果遇到比maxIndex大的下标元素,就把i下标传给maxIndex

5.最后minIndex中的元素一定是剩余数组中最小的元素,maxIndex中的元素一定是剩余数组中最大的元素

6.将minIndex中的元素与left交换,maxIndex中的元素与right交换

7.left++,right--,循环上述过程,最后数组实现从小到大排序

注意!!! 如下图

双向选择排序代码详解

public void DoubleSelectSort(int[] arr)
{
    //创建left让其指向0下标
    int left=0;

    //创建right让其指向arr.length-1下标
    int right=arr.length-1;

    //left等于right说明排序已经结束,所以left小于right
    while (left<right) {

        //创建minIndex和maxIndex每次循环将left传给他们
        int minIndex=left;
        int maxIndex=left;

        //i从left+1开始,每趟到right结束,一定要包括right所以i小于等于right
        for (int i = left + 1; i <= right; i++) {
    //如果遇到i下标元素值小于minIndex下标元素值,说明minIndex不是剩余数组元素最小值,将i传给minIndex
            if (arr[i] < arr[minIndex]) {
                minIndex = i;
            }
   //如果遇到i下标元素值大于maxIndex下标元素值,说明maxIndex不是剩余数组元素最大值,将i传给maxIndex
            if (arr[i] > arr[maxIndex]) {
                maxIndex = i;
            }
        }
        //将最小值和left交换
        swap(arr,left,minIndex);

        //如果maxIndex==left的话,而且left在上面已经和minIndex交换了
        if (maxIndex==left)
        {
            //我们需要将left交换的mainIndex传入maxIndex,这样maxIndex才是我们需要的
            maxIndex=minIndex;
        }
        //将最大值和right交换
        swap(arr,right,maxIndex);
            //left往前继续排序
            left++;
            //right往后继续排序
            right--;

    }
}
//下标元素交换代码
public void swap(int[] arr,int a,int b)
{
    int tmp=arr[a];
    arr[a]=arr[b];
    arr[b]=tmp;
}

堆排序

堆排序思路

1.先向下调整创建大根堆

2.堆排序,创建好的大根堆,堆顶元素和最后一个没有交换过位置的元素交换位置,然后将没有交换位置的元素,再向下调整成大根堆,然后循环这个过程

之前在堆的那篇博客中讲过堆排序这里就不说太多

堆排序代码详解

//建立大根堆
private void creatHeap(int[] arr)
 {
     //父亲结点从最后往上依次建立大根堆
     for (int parent=(arr.length-1-1)/2;parent>=0;parent--)
     {
         //向下调整成大根堆
    siftDown(arr,parent,arr.length);
     }
 }
 //向下调整
 private void siftDown(int[] arr,int parent,int len)
 {
     //找到孩子节点
     int child=parent*2+1;
     //孩子节点一定不能超过数组元素数量
     while (child<len)
     {
         //孩子结点+1也不能超过数组元素数量并且child下标元素小于child+1下标元素
         if (child+1<len&&arr[child]<arr[child+1])
         {
             //child++,child指向孩子中最大的那个
             child++;
         }
         //如果孩子中最大的那个大于父亲结点
         if (arr[child]>arr[parent])
         {
             //交换父亲和孩子结点的位置
             swap(arr,parent,child);
             //继续向下调整
             parent=child;
             child=parent*2+1;
         }else
         //如果孩子中最大的不大于父亲结点则说明建立成大根堆,直接退出
         {
             break;
         }
     }
 }
 //从小到大排序,堆排序
 public void heapSort(int[] arr)
 { //创建成大根堆
     creatHeap(arr);
     //从最后一个结点开始
     int end=arr.length-1;
     //当end>0的时候
     while (end>0) {
         //交换堆顶元素和最后一个元素位置,这样end位置会是整个堆最大的元素
         swap(arr,0,end);
         //向下排序,把除去end下标的往后元素,建立成大根堆
         siftDown(arr,0,end);
         //end--继续循环
         end--;
     }
 }

堆排序复杂度

时间复杂度:O(n*logn),

建立大根堆时间复杂度为O(n),

而堆排序交换堆顶元素和最后一个没有交换元素的位置(交换n次)并且要向下调整为大根堆(相当于根的深度也就是logn),时间复杂度为O(nlogn)

所以时间复杂度为O(nlogn)

空间复杂度:o(1),就一个数组

稳定性:不稳定,相同元素的位置可能会改变

冒泡排序

冒泡排序思路

1.如果相邻的两个元素,前面的大于后面的元素,那么就把这两个元素调换位置
2.继续往后走,按照以上的方式进行循环,可以保证每一趟最后一个元素一定是数组中最大的元素
3.n个元素要走n-1趟

上面看不懂请看下图

冒泡排序代码详解

public void bubbleSort(int[] arr)
{
//i为趟数,n个元素只需要n-1趟
for (int i=0;i<arr.length-1;i++)
{//创建一个flg将false传入
    boolean flg=false;
    //莓走完一趟,最后一个元素一定为最大值,最后一个元素不需要再交换
    for (int j=0;j<arr.length-1-i;j++)
    {
        //如果相邻元素前面的比后面的大
    if (arr[j]>arr[j+1])
    {
        //交换两个元素位置
       swap(arr,j,j+1);
       //如果交换顺序了,就把flg变为true
       flg=true;
    }
    }
    //如果!flg为true则说明没有交换顺序,也就说明数组已经有序了,不需要再进行排序
    if (!flg)
{
    break;
}
}
}

冒泡排序复杂度

时间复杂度:O(n^2),j需要进行n+n-1+n-2+n-3......1次比较,等差数列,时间复杂度为O(n^2)

空间复杂度:O(1),就一个数组

稳定性:稳定,无论怎么交换顺序,相同的元素位置不会改变

小结

没想到会写这么久,画图还有逻辑梳理真的很需要时间,喜欢的家人们麻烦给我个三连(点赞关注收藏!!!!)

求求了!!

博主有不好的地方请在评论区留言或者私信,我都会虚心接受!!!


 

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

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

相关文章

供应链投毒预警 | 开源供应链投毒202403月报发布啦!(含投毒案例分析)

悬镜供应链安全情报中心通过持续监测全网主流开源软件仓库&#xff0c;结合程序动静态分析方式对潜在风险的开源组件包进行动态跟踪和捕获&#xff0c;能够第一时间捕获开源组件仓库中的恶意投毒攻击。在2024年3月份&#xff0c;悬镜供应链安全情报中心在NPM官方仓库&#xff0…

2024华中杯A题完整1-3问py代码+完整思路16页+后续参考论文

A题太阳能路灯光伏板朝向问题 &#xff08;完整版资料文末获取&#xff09; 第1小问&#xff1a;计算每月15日的太阳直射强度和总能量 1. 理解太阳直射辐射和光伏板的关系**&#xff1a;光伏板接收太阳辐射并转化为电能&#xff0c;直射辐射对光伏板的效率影响最大。 2. 收集…

MES给制造业带来看得见的效益

作为连接生产控制系统和企业管理系统的纽带&#xff0c;MES为企业提供实时生产数据&#xff0c;帮助企业进行更加明智的决策&#xff0c;并实时调整生产管理&#xff0c;最终降低运营成本、提高运营利润和资产利用率、保证生产安全与合规。 MES主要功能包括工艺技术管理、生产…

面试题:一个 URL 在浏览器被输入到页面展现的过程中发生了什么

文章目录 前言一、回答二、深入追问 前言 这是一段~ 经典的旋律 ~&#xff0c;不好意思串台了&#xff0c;哈哈&#xff0c;这是一个经典的面试题&#xff1a;一个URL从浏览器到页面的过程中发生了什么&#xff0c;那么今天就带大家九浅一深来研究一下 觉得不错的同学可以加我…

波士顿动力抛弃液压机器人Atlas,推出全新电动化机器人,动作超灵活

本周&#xff0c;机器人科技巨头波士顿动力宣布液压Atlas退役&#xff0c;并推出了下一代产品——专为实际应用而设计的全电动Atlas机器人&#xff0c;这也意味着人形机器人迈出了商业化的第一步。 Atlas——人形机器人鼻祖 Atlas&#xff08;阿特拉斯&#xff09;这个名字最…

CTFHUB-技能树-Web前置技能-文件上传(前端验证—文件头检查)

CTFHUB-技能树-Web前置技能-文件上传&#xff08;前端验证—文件头检查&#xff09; 文章目录 CTFHUB-技能树-Web前置技能-文件上传&#xff08;前端验证—文件头检查&#xff09;前端验证—文件头检查题目解析 各种文件头标志 前端验证—文件头检查 题目考的是&#xff1a;pn…

【笔试强训】DFS、优先队列、滑动窗口笔试题目!

文章目录 1. 单词搜索2. 除 2 操作3. dd 爱框框 1. 单词搜索 题目链接 解题思路&#xff1a; DFS (深度优先遍历)&#xff0c;用一个 pos 记录要匹配单词 word 的位置&#xff0c;每次与 pos 进行匹配判断&#xff08;这样做的好处是不用把答案存下来&#xff09; 注意细节…

深入解析Nacos配置中心的动态配置更新技术

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! 在微服务架构中&#xff0c;配置管理变得尤为关键。Nacos&#xff0c;作为一个开源的、易于使用的、功能丰富的平台&#xff0c;为…

electron的webview和内嵌网页如何通信

在 Electron 的世界里&#xff0c;webview 标签相当于一个小盒子&#xff0c;里面可以装一个完整的网页&#xff0c;就像一个迷你浏览器。当你想和这个小盒子里的内容说话时&#xff08;也就是进行通信&#xff09;&#xff0c;这里有几个方法可以帮你做到&#xff1a; 这里只写…

轻量化模块整理,即插即用

轻量化模块整理&#xff0c;即插即用&#xff08;持续更新&#xff09; 整理一些轻量化的结构&#xff0c;作为知识储备&#xff0c;可以用到后续的项目和研究中 Mobilenetv3 深度可分离卷积 MobileNetV3 是一个轻量级的深度学习模型&#xff0c;专为移动和边缘设备上的高效…

conda配置多版本python

安装conda 以下任选下载 Anaconda Miniconda 配置conda环境变量 比如windows&#xff0c;在配置我的电脑中的环境变量&#xff0c;在系统变量的Path中新增下面内容 需要根据实际目录进行更改 D:\soft\miniconda3 D:\soft\miniconda3\Scripts D:\soft\miniconda3\Library\bi…

windows与linux双系统下,为linux系统/boot独立分区扩容

问题 安装ubuntu系统时&#xff0c;采用手动分区&#xff1a; 1. /boot &#xff1a;一般分配1G&#xff0c;电脑空间大可以分配4G 2. / &#xff1a;分配150-200G&#xff0c;类似windows C盘&#xff0c;存放系统环境&#xff1a;如ROS&#xff0c;python等 3. swap :…

PE文件(一)PE结构概述

PE结构简述 Windows操作系统是只能运行以内存4D 5A开头&#xff0c;翻译是MZ的可执行文件&#xff0c;也叫做PE结构文件&#xff0c;是以exe&#xff0c;.sys&#xff0c;.dll等等作为后缀的文件。而不同的操作系统能运行的可执行文件都是各自特有的&#xff0c;比如Linux可运…

图与图搜索算法

图搜索算法是一个非常重要的概念&#xff0c;它是计算机科学中图论和算法设计的基础部分。在开始讨论图搜索算法之前&#xff0c;我们需要先理解什么是图以及图的基本结构。 什么是图&#xff1f; 图&#xff08;Graph&#xff09;是一种非线性数据结构&#xff0c;它由一组点…

算法训练营第25天回溯(分割)

回溯算法&#xff08;分割&#xff09; 131.分割回文串 力扣题目链接(opens new window) 题目 给定一个字符串 s&#xff0c;将 s 分割成一些子串&#xff0c;使每个子串都是回文串。 返回 s 所有可能的分割方案。 示例: 输入: “aab” 输出: [ [“aa”,“b”], [“a”,“…

3D模型查看器开发实战【WebGL】

本文介绍如何从头开发一个包含3D 模型查看器的页面 - 尽管它非常简单&#xff0c;但你将学习的步骤也应该有助于构建其他类型的 Web 应用程序。 在自己的网站或博客里展示3D模型更简单的方式是使用NSDT 3DConvert提供的在线服务&#xff0c;无需任何开发工作&#xff0c;5分钟…

简单3步制作纸质英语绘本的mp3英语朗读音频

孩子学英语&#xff0c;需要看很多英语绘本&#xff0c;而且要听配套的音频。但有些英语绘本是没有对应音频的&#xff0c;下面简单三步&#xff0c;就可以将任意英语绘本制作出对应的英语朗读音频。 第一步&#xff0c;手机拍照做成PDF文件&#xff1a; 绘本每一页拍照后&…

模拟量化面试20问回答

原文链接 参考链接 量化的基本公式 对称均匀量化&#xff08;symmetric uniform quantization&#xff09; 对称量化将零点z限制为真实的0。注意对称均匀量化并不是关于零点对称。它还分为有符号和无符号。 signed量化公式 signed量化范围 8bit量化范围[-128, 127] signe…

使用python进行网站答题操作

介绍&#xff1a; 使用Python和DrissionPage模块编写自动化脚本&#xff0c;以模拟人的行为访问网站并获取题目答案进行自动答题。这个脚本似乎是为答题网站设计的&#xff0c;通过监控特定数据包地址来获取题目答案&#xff0c;并模拟点击正确答案进行答题。 代码中的逻辑包…

List实现(2)| LinkedList

参考&#xff1a;LinkedList 源码分析 在Java中&#xff0c;LinkedList是一个双向链表&#xff0c;实现了List和Deque接口&#xff0c;可以被当作列表&#xff08;List&#xff09;、队列&#xff08;Queue&#xff09;或者双端队列&#xff08;Deque&#xff09;使用。它允许…