排序算法理解浅析

2023-05-16

1.排序算法有很多,准确的理解可以帮我们快速实现工程问题,一种是比较排序,时间复杂度最少可达到O(n log n),主要有:冒泡排序选择排序插入排序归并排序堆排序快速排序等。另一种是非比较排序,时间复杂度可以达到O(n),主要有:计数排序,基数排序,桶排序等。本文主要介绍比较排序,下表给出了它们的复杂度 。


这里写图片描述


2.快速排序

快速排序是由东尼·霍尔所发展的一种排序算法。在平均或是最好的状况下,排序n个元素要O(nlogn)次比较。在最坏状况下则需要O(n^2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他O(nlogn)算法更快,因为它的内部循环可以在大部分的架构上很有效率地被实现出来。

快速排序使用分治策略把一个序列分为两个子序列,步骤为:

1.从序列中挑出一个元素,作为"基准"(pivot).
2。把所有比基准值小的元素放在基准前面,所有比基准值大的元素放在基准的后面(相同的数可以到任一边),这个称为分区(partition)操作。
3.对每个分区递归地进行步骤1~3,递归的结束条件是序列的大小是01,这时整体已经被排好序了。

动态效果如下:

这里写图片描述

快速排序是不稳定的排序算法,不稳定发生在基准元素与其它元素交换的时刻。

Java实现:

public class rank{
    /**
    *@param args
    */ 

    public static void main(String[] args){
        int[] intNum={32,4,232,4,4,5,27,8,3,9,1,55};
        quickSort qs = new quickSort();
        qs.data = intNum;
        qs.sort(0,qs.data.length-1);
        qs.display();
        System.out.println("hello world!");
    }
}


class quickSort{
    /**
    *quickSort
    */ 

    public int[] data;
    private int partition(int[] list,int low,int high){
        int key = list[low];//数组的第一个作为中轴
        while(low<high){
            while(low<high && list[high]>=key)
                high--;
            list[low]=list[high];//比中轴小的记录移到低端
            while(low<high && list[low]<=key)
                low++;
            list[high]=list[low];//比中轴大的记录移到高端
        }
        list[low]=key;//中轴记录到尾
        return low;//返回中轴的位置
    }

    public void sort(int low,int high){

        if(low<high){
            int result = partition(data,low,high);//一分为2
            // 
            sort(low,result-1);
            sort(result+1,high);
        }
    }

    public void display(){
        for(int i=0;i<data.length;i++){
            System.out.print(data[i]+" ");  
        }
        System.out.println();
    }
}

3.归并排序

归并排序(也称:合并排序)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,效率为O(nlogn),1945年由冯·诺伊曼首次提出,是一种稳定的算法。

步骤:

1.申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
2.设定两个指针,最初位置分别为两个已经排序序列的起始位置
3.比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
4.重复步骤3直到某一指针达到序列尾
5.将另一序列剩下的所有元素直接复制到合并序列尾

效果如下:

这里写图片描述

4.堆排序

堆排序是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构(通常堆是通过一维数组来实现的),并同时满足堆的性质:即子结点的键值总是小于(或者大于)它的父节点。堆排序是不稳定的排序算法,不稳定发生在堆顶元素与A[i]交换的时刻。

步骤:

1.创建一个堆
2.把堆顶元素(最大值)和堆尾元素互换
3.把堆的尺寸缩小1,并调用heapify(A, 0)从新的堆顶元素开始进行堆调整
4.重复步骤2,直到堆的尺寸为1

这里写图片描述

5.选择排序:

选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾。以此类推,直到所有元素均排序完毕。选择排序是不稳定的排序算法,不稳定发生在最小元素与A[i]交换的时刻。

这里写图片描述

6.冒泡排序

冒泡排序(Bubble Sort,泡沫排序或气泡排序)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

步骤:

1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
3.针对所有的元素重复以上的步骤,除了最后一个。
4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

这里写图片描述

7.插入排序

插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。就像这样,你会的

这里写图片描述

插入排序不适合对于数据量比较大的排序应用。但是,如果需要排序的数据量很小,比如量级小于千,那么插入排序还是一个不错的选择。

步骤:

1.从第一个元素开始,该元素可以认为已经被排序
2.取出下一个元素,在已经排序的元素序列中从后向前扫描
3.如果该元素(已排序)大于新元素,将该元素移到下一位置
4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
将新元素插入到该位置中
5.重复步骤2

这里写图片描述

8.希尔排序

希尔排序,也称递减增量排序算法,是插入排序的一种高速而稳定的改进版本。希尔排序是基于插入排序的以下两点性质而提出改进方法的:1、插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率。2、但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位。希尔排序是不稳定的排序算法,虽然一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱。希尔排序通过将比较的全部元素分为几个区域来提升插入排序的性能。这样可以让一个元素可以一次性地朝最终位置前进一大步。然后算法再取越来越小的步长进行排序,算法的最后一步就是普通的插入排序,但是到了这步,需排序的数据几乎是已排好的了(此时插入排序较快)。假设有一个很小的数据在一个已按升序排好序的数组的末端。如果用复杂度为O(n^2)的排序(冒泡排序或直接插入排序),可能会进行n次的比较和交换才能将该数据移至正确位置。而希尔排序会用较大的步长移动数据,所以小数据只需进行少数比较和交换即可到正确位置。

这里写图片描述


参考文献:

1.http://blog.jobbole.com/11745/
2.http://www.cnblogs.com/eniac12/p/5329396.html

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

排序算法理解浅析 的相关文章

  • winScp 连接 FilEZillA报(由于目标计算机积极拒绝,无法连接)

    场景 xff1a 服务器一台 xff1b 本地台式机一台 xff0c 为了文件传输方便 xff0c 在服务器上使用FilEZillA搭建了FTP xff0c 在本地使用WinScp进行连接 问题 xff1a 首先FTP搭建没问题 xff0c
  • 关于 Raspberry Pi3 使用 Intel® RealSense™ D400 cameras的简单介绍

    Raspberry Pi Raspberry pi 可以称为个人微型电脑 xff0c 虽然它的性能无法与普通电脑相比 xff0c 但是它在很多方面都给我们带来了惊喜 xff0c 它的特点是便于携带 xff0c 功能基本和普通电脑一样 xff
  • 安装好后 实例启动出现问题

    错误如上正在排错中 File 34 usr lib python2 7 site packages nova conductor manager py 34 line 671 in build instances request spec
  • gazebo仿真之plugin系列一

    官网教程 xff1a http gazebosim org tutorials tut 61 plugins hello world amp cat 61 write plugin 本次内容涉及五个方面 xff1a plugin的基本介绍与
  • gazebo官网教程之快速开始

    英文教程 xff1a http gazebosim org tutorials tut 61 quick start amp cat 61 get started 一 运行gazebo 打开有默认环境的gazebo只需要三步 xff1a 1
  • 基于unity无人机3D仿真《一》

    基于unity无人机3D仿真 一 实现无人机的模型的制作 运动学关系 姿态角等 xff1b 实现无人机各种姿态运动 一 目前的效果 二 无人机模型 制作软件 xff1a maya 模型结构 xff1a 三 开发平台 unity2017 43
  • 比特、字节转换

    1bite xff08 比特 xff09 61 1字节 数字 xff1a 1字符 61 1字节 英文 xff1a 1字符 61 1字节 汉字 xff1a 1字符 61 2字节 在ASCII码中 xff0c 一个英文字母 xff08 不分大小
  • Unity无人机仿真github项目

    本人本科生有幸得到导师的指导 xff0c 对Unity这个平台学习已有一段时间 该平台在搭建自主仿真平台方面确实有很大优势 下面是在学习过程中收集到的一些多旋翼无人机仿真的github项目 xff0c 可供需要的快速学习 xff08 推荐先
  • matlab2020a中使用TrueTime工具

    环境 xff1a matlab版本 xff1a 2020a 参考文章 网络控制系统仿真 xff1a Truetime2 0工具箱安装 xff08 win10 43 matlab R2017b xff09 目标 xff1a 在matlab20
  • ros的init机制续篇

    这篇博客主要探讨init的实现过程 ros span class token double colon punctuation span span class token function init span span class toke
  • 基于Unity构建机器人的数字孪生平台系列1—介绍

    1 0 简介 本系列博客将开源近两年结合Unity和多旋翼无人机的相关工作 xff0c 涵盖仿真 建模 全局云端通信网络 本地局部通信网络 ROS 43 Unity VR等方面内容 该工作完整构建以虚控实 xff0c 沉浸式VR交互 xff
  • 基于Unity构建机器人的数字孪生平台系列2—四旋翼无人机三维模型

    系列2的主要内容是探讨如何自己构建一个模型并且导入Unity 1 简介 3D仿真与其他类型仿真的一大区别是三维场景和三维模型 为了实现对某个对象的仿真 xff0c 模型是必须的 当然 xff0c 针对不同的仿真任务 xff0c 需要描述对象
  • 模式识别实现之人脸识别(matlab)

    描述 用有监督学习机制设计并实现模式识别方法 xff0c 用于进行人脸面部特征识别 xff0c 如性别 xff08 男性 女性 xff09 年龄 xff08 儿童 青少年 成年 老年 xff09 佩戴眼镜 xff08 是 否 xff09 戴
  • 无人机自动驾驶GAAS学习一

    building GAAS environment 基本依赖项 pip install pandas jinja2 pyserial cerberus pyulog numpy toml pyquaternion Q1 程序 pip 尚未安
  • 无人机学习之launch文件的学习

    官网教程 xff1a http wiki ros org roslaunch XML xff08 1 xff09 ros系统launch文件出现的原因 xff1a 一个功能的实现包括比较多的节点的运行 xff0c 并且每个节点的启动是有顺序
  • 配置最基础的linux系统——Centos6.x版本

    自然是用到虚拟机了 xff0c Vmware是我常用的 xff0c 这里建立一个虚拟的裸机很简单 xff0c 有两点是要说明的 1 最大磁盘大小 xff0c 这个默认的是最小大小 xff0c 不能设的别它还小了 xff0c 否则启动不了Ce
  • matlab实现画散点图(一个x对应多个y)

    1 具体实现是 xff0c 首选导入数据 aray 61 importdata 位置 xff1b m n 61 size array 2 x轴间距设置 x 61 1 1 m 3 处理数组数据 figure 1 for i 61 1 1 n
  • VINS-Mono源码分析7— pose_graph2(四自由度位姿图优化)

    VINS Mono源码分析7 pose graph2 在上一篇博文中 xff0c 大概分析了一下VINS Mono回环检测和重定位的代码实现 xff0c 这里主要分析 四自由度的位姿图优化 关于这部分的原理可以参考VINS Mono论文第8
  • VINS-Mono中的DBoW2关键代码注释

    VINS Mono中的DBoW2关键代码注释 在阅读VINS Mono源码时对DBoW2中代码顺手做的注释 xff0c 怕以后会忘记 xff0c 在这里记录一下 xff0c 注释有不当之处 xff0c 望各位大神看到后多多指点 理论参考高翔

随机推荐