排序个人总结

news2024/12/26 12:24:57

插入排序

思路;定义 和 j,默认 i 前面的数都是有序的,j 定义为 i 的前一个数,把 i 的值给tmp,tmp与j对应的值进行比较,如果arr[j] > tmp,将arr[j] (大的数前移一位),如下图

代码:

    //插入排序
    //每次循环i前面的值都是有序的
    public void insertSort(int[] arr){

        for (int i = 1; i < arr.length; i++) {
            int j = i-1;        //j定义为i的前一个数
            int tmp = arr[i];   //将arr[i]设置为临时变量,插入i前面有序的数组中
            for(;j>=0;j--){

                if(arr[j]>tmp){
                    arr[j+1]=arr[j];        //前移
                }else {
                    //代表前面已经有序了
                    //arr[j+1]=tmp;       //将tmp放回到原来的位置
                    break;
                }
            }
            arr[j+1]=tmp;       //跳出循环的时候,j已经小于0了,

        }

    }

特点:时间复杂度

最好情况下:数据都是有序的情况下:O(N)

最坏情况下:数据完全逆序的O(n^2)

空间复杂度 O(1)

稳定性:稳定的

希尔排序

思路:数组分组进行排序,如下

10个数,分5组,组内进行排序,组内使用插入排序,

再分两组,组内进行排序,

最后分一组,排序完成

代码如下

//希尔排序
    public void shellSort(int[] arr){
        int gap = arr.length;   //gap分的组,
        while (gap>1){
            gap = gap/3 +1 ;
            shell( arr , gap);      //将分好的组进行插入排序
        }

    }
    private void shell(int[] arr, int gap){     //这里和插入排序思路一样,只是插入排序中,            
                                                //我们按照1来进行计算,这里按照gap来进行计算
                                                //建议:先把插入排序写完,再写希尔排序
        for(int i = gap;i<arr.length;i++){
            int j = i-gap;
            int tmp = arr[i];

            for(;j>=0;j-=gap){
                if(arr[j]>tmp){
                    arr[j+gap]=arr[j];              //大的数后移
                }else {
                    break;
                }
            }
            arr[j+gap]=tmp;
        }
    }

特点:不稳定排序,时间复杂度不好计算

选择排序

思路;定义一个i下标,和 j= i + 1,将i下标定义为minIndex,j向后遍历,寻找i后面比minIndex还要小的值,找到了就重新定义minIndex,循环结束后和i的位置进行交换

代码如下:

    //选择排序
    public void selectSort(int[] arr){
        for(int i = 0;i<arr.length;i++){
            int j = i+1;                //j在i的前一个数,j向后寻找比i下标值小的数,找到了就和    
                                        //i下标的值交换,找不到就向后移动
            int minIndex = i;
            for(;j<arr.length;j++){
                if(arr[j]<arr[minIndex]){
                    minIndex=j;         //跟新最小值下标
                }
            }
            //循环结束后,找到了i前面的最小值小标
            //将i的位置和最小值下标交换
            Swap(arr,i,minIndex);

        }

    }
    private static void Swap(int[] arr,int a,int b){
        int tmp = arr[a];
        arr[a]=arr[b];
        arr[b]=tmp;

    }

特点:时间复杂度O(N^2)

空间复杂度O(1)

稳定性:不稳定

堆排序

堆排序需要将数组变成大根堆。

因为是大根堆,所以头节点是最大的,将头节点和尾节点进行交换,让后向下调整,每次调整后都将最大的节点放到尾部,调整完后就是从小到大的排序

代码如下

//堆排序
    //堆排序首先需要创建大根堆,
    public void headSort(int[] arr){
        //先将数组变成大根堆
        createBigHead(arr);
        int end = arr.length -1;
        while (end > 0){
            Swap(arr,0,end);            //交换头和最后一位节点进行向下调整
            shiftDown(arr,0,end);
            end--;
        }
    }
//创建大根堆/采用向下调整的方法
    public void createBigHead(int [] arr){
        int end = arr.length;
       int parent = (arr.length-1-1)/2;         //最后一颗子树的父亲节点,开始向下调整
        for(;parent>=0;parent--){
            shiftDown(arr,parent,end);
        }
    }
    private static void shiftDown(int[] arr,int parent,int end){
        int child = 2*parent +1 ;               //左孩子节点
        while (child<end){
            //找出孩子节点中最大的一个,和父亲节点进行交换
            if(child+1<end&&arr[child]<arr[child+1]){
                child=child+1;
            }
            if(arr[child]>arr[parent]){
                Swap(arr,child,parent);
                //交换完成后父亲和孩子节点向下调整
                parent=child;
                child = 2*parent+1;
            }else {
                break;
            }
        }

    }

快速排序

思路:

代码如下

public void quickSort(int [] arr){
        int start = 0;              //设置开始和结束
        int end = arr.length-1;     
        quick(arr,start,end);       //调用方法
    }
    public void quick(int[] arr,int start,int end){

        if(start>=end){         //当开始大于结束时,递归结束
            return;
        }
        int pivot = partition(arr,start,end);       
        quick(arr,start,pivot-1);
        quick(arr,pivot+1,end);

    }

    public int partition(int[] arr, int left ,int right){
        int tmp = arr[left];            //设置第一个值为基准
        int i = left;                   //保留第一个值的位置

        while (left<right){

             while (left<right&&arr[right]>=tmp){
                right--;                            //从右边开始找,找到比tmp小的值让后停下来
            }            


             while (left<right&&arr[left]<=tmp){     //第一个判定条件是防止整个数组的值都比tmp小,从而导致数组越界
                left++;                             //从左边开始找,找到比tmp大的值让后停下来
            }
           
            Swap(arr,left,right);                   //交换,两个值,有可能left和right相等,相等就交换自己

        }
        Swap(arr,i,left);                       //把相遇的点和第一位交换
        return left;                            //返回left和right相遇的点

    }

上述是快速排序的一种方法,下面是第二种方法,挖坑法

public int partition2(int [] arr,int left,int right){
        int tmp = arr[left];
        int i = left;
        while (left<right){

            while (left<right&&arr[right]>=tmp){
                right--;
            }
            arr[left]=arr[right];           //右边找到比tmp小的,直接交换


            while (left<right&&arr[left]<=tmp){
                left++;
            }
            arr[right]=arr[left];       //左边找到比tmp大的,直接交换




        }
        arr[left]=tmp;          //将取出的tmp放回到空格处
        return left;
    }

这里有个疑问,为啥

while (left<right&&arr[left]<=tmp){
    left++;
}
arr[right]=arr[left];       //左边找到比tmp大的,直接交换
while (left<right&&arr[right]>=tmp){
    right--;
}
arr[left]=arr[right];           //右边找到比tmp小的,直接交换

这两个循环换一下执行顺序就出错了,不理解我就死记了

特点:时间复杂度n*logn,是不稳定的排序

归并排序

思路:将数组分裂,分裂结束后再进行组内合并

合并的时候需要创建一个新的数组用来存放排序好的数组

//归并排序
    public void mergeSort(int[] arr){
        mergeFunc(arr,0,arr.length-1);
    }

    public void mergeFunc(int[] arr,int left,int right){
        if(left>=right){
            return;
        }
        //进行分裂
        int mid = (left+right)/2;
        mergeFunc(arr,left,mid);        //分裂左边
        mergeFunc(arr,mid+1,right);     //分裂右边
        //分裂完后进行合并
        merge( arr, left,mid,right);

    }
    public void merge(int[] arr,int left,int mid,int right){
        int s1 = left;
        int e1 = mid;
        int s2 = mid+1;
        int e2 = right;
        int[] tmp = new int[(right-left)+1];
        int k = 0;
        while (s1<=e1&&s2<=e2){  //代表分裂的这段有数据
            //s1和s2进行比较
           if(arr[s1]<=arr[s2]){
               tmp[k++]=arr[s1++];      //谁小放谁进去
           }else {
               tmp[k++]=arr[s2++];
           }
        }
        while (s1<=e1){              //如果有一个没有数据了,直接把剩下的全放进去
            tmp[k++]=arr[s1++];
        }
        while (s2<=e2){
            tmp[k++]=arr[s2++];
        }
        
        //再把数据拷贝回原来的数组中
        for (int i = 0; i < k; i++) {
            arr[i+left]=tmp[i];        //拷贝回原来的数组
        }

    }

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

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

相关文章

【亲子英语】英语故事有声绘本分享

文章目录 一、视觉与听觉的双重盛宴二、语言学习的最佳伙伴三、亲子共读的温馨时光四、适用人群广泛&#xff0c;随时随地学习五、获取方式 在这个快速发展的时代&#xff0c;英语学习已经不再局限于课本和课堂。特别是对于活泼好动的孩子们来说&#xff0c;一种既有趣又高效的…

open-resty 服务安装jwt插件

作者&#xff1a;程序那点事儿 日期&#xff1a;2023/11/16 22:07 lua-resty-jwt 插件 如果想使用Lua识别用户令牌&#xff0c;我们需要引入lua-resty-jwt模块&#xff0c;是用于 ngx_lua 和 LuaJIT 的 Lua 实现库&#xff0c;在该模块能实现Jwt令牌生成、Jwt令牌校验。 下载…

9.25作业

手动实现队列 代码如下 MyQueue.h #ifndef MYQUEUE_H #define MYQUEUE_H #include <iostream> #include <cstring> using namespace std;class Queue{ private:char* data; //字符串数据int len; //当前数量int size; //最大容量int front; //头索引int …

uboot — uboot命令的使用

uboot的命令繁多&#xff0c;下文只对工作中常用到的命令进行记录&#xff0c;其余命令待用到时再查查资料也不迟 一、环境变量操作命令 1、printenv 打印环境变量 2、setenv 修改环境变量/新建环境变量 3、saveenv 保存环境变量/删除环境变量&#xff08;给环境变量赋空值…

巴特沃斯滤波器的MATLAB实现

一、引言 巴特沃斯滤波器&#xff08;Butterworth Filter&#xff09;&#xff0c;是滤波器的一种&#xff0c;其主要特点是通频带的频率响应曲线最平滑。这种滤波器最先由英国工程师斯蒂芬巴特沃斯(StephenButterworth)在1930年发表在英国《无线电工程》期刊的一篇论文中提出的…

基于vue框架的村务综合服务系统8p0l3(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;居民,村委,支部,公告信息,通讯录,重点户 开题报告内容 基于Vue框架的村务综合服务系统开题报告 一、引言 随着信息化时代的深入发展&#xff0c;农村社会治理模式正经历着深刻的变革。传统村务管理方式往往存在信息不对称、效率低下、…

【SpringBoot整合Redis测试Redis集群案例】

1、第一步&#xff0c;创建springboot项目&#xff0c;并导入依赖 如图&#xff0c;创建项目遇到的第一个问题就是&#xff0c;当type选择maven&#xff0c;jdk选择1.8时&#xff0c;java部分没办法选择1.8的版本&#xff0c;这怎么办呢&#xff1f; 原因&#xff1a;搜了一下…

【C++ Primer Plus习题】17.7

问题: 解答: #include <iostream> #include <vector> #include <string> #include <fstream> #include <algorithm>using namespace std;const int LIMIT 50;void ShowStr(const string& str); void GetStrs(ifstream& fin, vector<…

【多线程】面试高频考点!JUC常见类的详细总结,建议收藏!

&#x1f490;个人主页&#xff1a;初晴~ &#x1f4da;相关专栏&#xff1a;多线程 / javaEE初阶 JUC是“Java Util Concurrency”的缩写&#xff0c;指的是Java并发工具包&#xff0c;它位于java.util.concurrent包及其子包中。JUC包提供了大量用于构建并发应用程序的工具和…

简历信息提取系统源码分享

简历信息提取检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

C++之stack 和 queue

目录 前言 1.stack的介绍和使用 1.1 stack的介绍 1.2 stack的使用 1.3 stack 的模拟 2. queue的介绍和使用 2.1 queue的介绍 2.2 queue的使用 2.3 queue的模拟 3.适配器 3.1 什么是适配器 3.2 STL标准库中stack和queue的底层结构 3.3 deque 的介绍&#xff08;了解&…

每日OJ题_牛客_ 腐烂的苹果_多源BFS_C++_Java

目录 牛客_腐烂的苹果&#xff08;多源 BFS&#xff09; 题目解析 C代码 Java代码 牛客_腐烂的苹果&#xff08;多源 BFS&#xff09; 腐烂的苹果_牛客题霸_牛客网 题目解析 多源 BFS 问题&#xff0c;固定套路&#xff0c;BFS学习 &#xff1a;Offer必备算法28_多源BFS_…

【C++算法】哈希表

哈希表介绍&#xff1a; 1.哈希表是什么&#xff1f; 存储数据的容器 2.哈希表有什么用&#xff1f; “快速”查找某个元素——O(N) 3.什么时候使用哈希表&#xff1f; 频繁的查找某一个数的时候&#xff0c;频繁也可以使用二分&#xff08;有序&#xff09; 4.怎么用哈希表&…

cadence多版本启动问题

一、问题描述 电脑上安装了 17.4 和16.6两个版本打开16.6时会弹出 **原因&#xff1a;**使用Allegro设计PCB时&#xff0c;当关闭软件后&#xff0c;再次打开Allegro软件&#xff0c;打开的文件为上一次操作过的.brd文件&#xff0c;这是Allegro软件安装的默认设置。 二、解…

单体项目中定时任务的实现-详细教程

单体项目中定时任务的实现 在企业开发中&#xff0c;遇到的项目无非就两种&#xff0c;单体项目和分布式项目 单体项目中实现定时任务有以下几种方式 1. 使用Timer实现定时任务&#xff08;不常用&#xff09; 1.1、JDK1.3推出的定时任务实现工具类java.util.Timer 1.2、API…

学习MRI处理过程中搜到的宝藏网站

今天浏览网页查到了一些宝藏网站&#xff0c;正好记录一下&#xff0c;后面搜到好东东再接着填充&#xff0c;方便查阅~ &#xff08;1&#xff09;牛人网站 这个网站是在搜集seed关键词时发现的&#xff0c;用pdf文档记录&#xff0c;可下载查阅&#xff0c;条理清晰&#xf…

Python | Leetcode Python题解之第433题最小基因变化

题目&#xff1a; 题解&#xff1a; class Solution:def minMutation(self, start: str, end: str, bank: List[str]) -> int:if start end:return 0def diffOne(s: str, t: str) -> bool:return sum(x ! y for x, y in zip(s, t)) 1m len(bank)adj [[] for _ in ra…

基于Node.js+Express+MySQL+VUE实现的在线电影视频点播网站管理系统的设计与实现

1. 引言 随着互联网技术的快速发展和普及&#xff0c;人们获取信息的方式发生了巨大变化&#xff0c;其中在线视频点播服务因其便捷性和多样性而受到广泛欢迎。在线电影视频点播网站作为这一领域的代表&#xff0c;不仅需要满足用户观看需求&#xff0c;同时也需为管理员提供高…

架构设计读后有感——设计流程

架构也是有套路的 绝大部分的公司中&#xff0c;架构师都是技术人员的终极方向&#xff0c;是技术金字塔的顶端&#xff0c;那么普通人员要想走上这条路&#xff0c;需要掌握适当的方法&#xff0c;逐步完善架构 &#x1f3f9;1 有的放矢——识别复杂度 分析复杂性是设计架构的…

vscode 代码格式setting设置

{"editor.tabSize": 2,"eslint.validate": ["javascript", // 用eslint的规则检测js文件"vue","html","typescript","typescriptreact"],"editor.codeActionsOnSave": {"source.fixAll…