排序1:几种基本的排序方法

2023-11-01

在数据结构课里,一般会将查找和排序放在一起,大部分人都会感觉查找比排序容易。但是我们研究过算法之后就会发现查找远远难于排序,因为常见的排序方法是相对固定的。而查找除了最基本的二分查找外,还包含非常广的内容,二叉树,各种树,Hash,大数据下的查找,而动态规划和回溯等本身也是在寻找某个特定的目标。所以查找散步在整个算法中,我们不单独列了。

排序我们先看看都有哪些常见的算法。还有一些基于某些特征的典型算法题,之后我们就一边整理排序算法,一边见识一下这些变形题。
 常见的排序方法有:1冒泡排序。2.选择排序。3 插入排序。4.快速排序。5.归并排序。6.快速排序。7.归并排序。8.堆排序。9.优先级队列。10.桶排序。11.基数排序。12.希尔排序。13位图排序.

本文我们先看几个基本的算法。

1.调用库函数Arrays.sort

这个在比较复杂的算法题中可以直接用,如果就是为了考察排序,那自然不行。

import java.util.Arrays;
public class Solution {
    public int[] MySort (int[] arr) {
        //调用库函数sort;
        Arrays.sort(arr);
        return arr;
    }
}

而我们后面在桶排序中,这是一个比较复杂的算法,期间还需要用到排序算法,此时就顺理成章使用库方法了。

2.冒泡排序BubbleSort

最基本的排序算法,这个题目就是热身或者在某些场景下使用其变型方法,比如前面链表里奇偶调整的例子中就用到了。在考察排序的题里是不能用的,因为会出现运行超时的情况。

  public int[] MySort (int[] arr) {
        if(arr.length<2){
            return arr;
        }
 
        for(int i=0;i<arr.length-1;i++){
            for(int j=0;j<arr.length-i-1;j++){
                if(arr[j]>arr[j+1]){
                    swap(arr,j,j+1);
                }
            }
        }
        return arr;
    }

    public void swap(int[]arr,int i, int j){
        int tmp;
        tmp=arr[i];
        arr[i]=arr[j];
        arr[j]=tmp;
    }

3.选择排序

选择排序和冒泡排序有一点点像,选择排序是默认前面都是已经排序好的,然后从后面 选择最小的放在前面排序好的的后面,首先第一轮循环的时候默认的排序好的为空,然 后从后面选择最小的放到数组的第一个位置,第二轮循环的时候默认第一个元素是已经 排序好的,然后从剩下的找出最小的放到数组的第二个位置,第三轮循环的时候默认前 两个都是已经排序好的,然后再从剩下的选择一个最小的放到数组的第三个位置,以此 类推。下面看一下代码。

 public static void selectSort(int[] array) {
        for (int i = 0; i < array.length; i++) {
            int index = i;
            for (int j = i + 1; j < array.length; j++) {
                if (array[index] > array[j]) {
                    index = j;
                }
            }
            if (i != index) {
                swap(array, i, index);
            }
        }
    }

    public static void swap(int[] A, int i, int j) {
        A[i] ^= A[j];
        A[j] ^= A[i];
        A[i] ^= A[j];
    }

我们看到每轮循环的时候并没有直接交换,而是从他后面的序列中找到最小的记录一下 他的index索引,最后再交换.

这里的交换方法是不是和平时见的不一样,这种位操作的方式效率更高,如果理解并在面试时写出来,也是个不错的加分项,常规是定义一个临时变量,然后交换。其实这里还有一个骚写法:

 public static void swap2(int[] A, int i, int j) {
        A[i] = A[i] + A[j];
        A[j] = A[i] - A[j];
        A[i] = A[i] + A[j];
         
    }

上面理解已经是合格了,为了加深理解,下面看一下他的递归是怎么实现的。

public static void selectSortRe(int[] array, int index) {
        if (index == array.length)
            return;
        int min = index, i = index + 1;
        for (; i < array.length; i++) {
            if (array[i] < array[min]) min = i;
        }
        if (min != index) {
            swap(array, index, min);
        }
        selectSortRe(array, ++index);
}

5. 插入排序

插入排序的原理是默认前面的元素都是已经排序好的,然后从后面逐个读取插入到前面排序好的合适的位置,就相当于打扑克的时候每获取一张牌的时候就插入到合适的位置一样。插入排序可以分为两种,一种是直接插入还一种是二分法插入,直接插入的原理比较简单,就是往前逐个查找直到找到合适的位置然后插入,二分法插入是先折半查找,找到合适的位置然后再插入。说到二分法查找,等排序完之后就会介绍查找,有多种包括斐波那契查找,哈希查找,二分法查找等多个,其实这里面也可以使用,我们先看一下简单的直接插入排序代码:

public int[] MySort (int[] arr) {
        if(arr==null || arr.length<2){
            return null;
        }
        for(int i=1;i<arr.length;i++){
            int j=i;
            int temp=arr[i];
            for(;j>0;j--){
                if(arr[j-1]>temp){
                    arr[j]=arr[j-1];
                }else{
                    break;
                }
            }
            arr[j]=temp;
        }
        return arr;
 }

这里还可以在查找的时候使用二分查找,数据量大的时候,效率肯定更高,但是编写的难度也高了:

public int[] MySort (int[] arr) {
        if(arr==null || arr.length<2){
            return null;
        }
        for(int i=1;i<arr.length;i++){
          if(arr[i-1]>arr[i]){
              int key=arr[i];
              int low=0;
              int high=i-1;
              while(low<=high){
                  int mid=(low+high)>>1;
                  if(arr[mid]>key){
                      high=mid-1;
                  }else{
                      low=mid+1;
                  }
              }
              for(int j=i;j>low;j--){
                  arr[j]=arr[j-1];
              }
              arr[low]=key;
          }
        }
        return arr;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

排序1:几种基本的排序方法 的相关文章

随机推荐

  • 网狐荣耀手机端内核源码

    网狐荣耀手机端内核源码 实测 可用 链接 https pan baidu com s 1YT GWgFCDxYqrez7e EJqw 提取码 0ezk
  • 因特网(Internet)的概述

    一 因特网的概述 1 主机 连接在因特网上的计算机都称为主机 2 网络 网络 network 由若干节点 node 和连接这些的结点的链路 link 组成 互联网由网络组成 3 Internet和internet的区别 internet 互
  • 线性代数的本质(四)——行列式

    文章目录 行列式 二阶行列式 n n n 阶行列式 行列式的性质 克拉默法则 行列式的几何理解 行列式 二阶行列式 行列式引自对线性方程组的求解 考虑两个方程的二元线性方程组
  • Flask入门教程(3)-表单验证和WTF扩展

    03 01 普通的表单验证 03 02 flash消息闪现 html代码
  • 自顶向下语法分析(top-down parsing)

    自顶向下语法分析 top down parsing 有回溯的自顶向下分析 非预测分析法 无回溯的自顶向下分析 预测分析法 FIRST集和FOLLOW集 两种预测分析算法 LL 1 文法 文法转换 消除左递归 提取左公因子 输入程序经过词法分
  • react-router V6 版本的使用(自己封装了 Redirect,使用 useRoute 等)

    react router V6 版本的使用 自己封装了 Redirect等 IndexRouter js 使用useRoute 做全局路由的搭建 包括嵌套路由 路由重定向 路由拦截 自己封装 路由懒加载 做了一个简单的封装 等 import
  • 五线谱音名和组别对照表_五线谱简谱对照表(五线谱1234567表示图)

    五线谱音阶图 音乐符号是世界上常用的符号 用来记录笔记的五行平行线称为谱线 工作人员有5条线 在这5条线中有4个房间 每行和每个房间上方都有一个音符 五条线和四个房间是不够的 并且可以添加其他房间和线 在学习职员记号之后 将始终使用它 因为
  • 入职华为外包一个月后,我离职向“北上广深”流浪了...

    这次来聊一个大家可能也比较关心的问题 那就是就业城市选择的问题 而谈到这个问题 就不可避免地会谈到一些关于 机会 技术氛围 跳槽 薪资水平 等等一系列问题 正好 这也是大家所常问的 我只能说来聊聊我的感受吧 我觉得城市选择非常重要 尤其对我
  • 链表大小排序方法c语言,5 种排序算法--C语言链表

    源码地址 GitHub https github com GYT0313 C DataStructure blob master sortIn5 c 包括 冒泡排序 快速排序 选择排序 插入排序 希尔排序 运行 注意 快速排序的核心代码应该
  • C#中属性赋值的步骤以及语法详解

    首先我们要先知道什么是C C 是由微软 Microsoft 开发 其中还包括C 面向过程 C C 是一个简单的 现代的 通用的 面向对象的编程语言 面向对象 是一种解决问题的思想 那么什么是对象 在程序员的眼中自己身边万物都可以理解为对象
  • python运行js文件_python-execjs(调用js)

    一 安装 pip3 install PyExecJS 电脑上要有nodejs环境 二 使用 一 获取js字符串 首先将js保存至于本地文件或者你可以可以直接读到内存 必须让js以python基础教程字符串的形式展示 注意点 字符串中不要出现
  • Go 获取10分钟前的时间,一天前的时间。。。

    time Now Add time Minute 10 golang的time包里面有个AddDate方法 nTime time Now yesTime nTime AddDate 0 0 1 logDay yesTime Format 2
  • FireFox浏览器的about:config参数大全及其具体用途介绍

    FireFox浏览器的about config参数大全及其具体用途介绍 注意 这还远不是所有的about config参数 由于设置参数太多 官方也只提供英文版本的说明 这里提供的FireFox about config配置参数并不完整 希
  • MSP430F5529学习笔记(4)——按键点灯

    MSP430F5529学习笔记 3 实现LED闪烁和呼吸灯 独立按键工作原理 目录 按键扫描 原理图分析 写程序 按下s1点亮LED1 1 首先我们需要告诉单片机 P2 1是输入还是输出 2 配置IO是否允许上下拉 3 配置IO是上拉还是下
  • 入坑前端:一文搞懂 Flex 布局

    前言 Flex 这个布局前前后后看了3次 第一次学的时候 发现有十几个属性值没耐心看完就没往下学了 作罢 第二次去看的时候大概搞明了Flex每个属性的用法 可没过几天又全部忘光了 第三次了解 Flex 于是就有了这篇笔记 估计是全网最易懂的
  • MyBatis 特殊字符转义拦截器 针对(_、\、%)

    一 问题反馈 今天公司测试向我反馈 系统用户模糊查询功能在用户名称包含特殊字符时 无法正常查询结果 二 问题验证 1 当like中包含 时 查询仍为全部 即 like 查询出来的结果与like 一致 并不能查询出实际字段中包含有 特殊字符的
  • 构建Camel和Raspberry Pi物联网

    该项目基于Camel技术 项目为IoT社区提供了一些很棒的新东西 这些东西是将电子设备 i2c SPI gpio tinkerforge 和云 pubnub cloudlet mqtt 连接在一起的新的物联网组件 在本实验中 我们将展示如何
  • 卡特兰数——括号匹配问题

    卡特兰数的递推公式是F n k 1 n F k 1 F n k k 0 n 1 F k F n k 1 一般性公式为F n C 2n n n 1 可以描述的问题有 1 n个元素的二叉查找树有多少种 2 n n棋盘从左下角走到右上角而不穿过主
  • Go语言-log

    1 log包 作为程序调试手段和运行记录 log是非常重要的 现在多数情况下并不是通过某个调试器来进行debug了 而是通过打log的方式观察和调试程序 可以根据自己的需要实现log功能 Go语言本身也已经内置了log包 这里研究Go语言内
  • 排序1:几种基本的排序方法

    在数据结构课里 一般会将查找和排序放在一起 大部分人都会感觉查找比排序容易 但是我们研究过算法之后就会发现查找远远难于排序 因为常见的排序方法是相对固定的 而查找除了最基本的二分查找外 还包含非常广的内容 二叉树 各种树 Hash 大数据下