`
sbpya
  • 浏览: 618821 次
  • 性别: Icon_minigender_1
  • 来自: 杭州,长沙
社区版块
存档分类
最新评论

算法---排序

    博客分类:
  • Java
阅读更多

排序的关键字

  1. 时间复杂度:整个排序算法运行所需要的时间。

  2. 空间复杂度:排序算法运行过程汇总所需要额外空间

  3. 稳定性:若待排的序列中有大小相同的两个数,若整个排序过程中不存在两数次序交换的可能新内阁,则该排序算法是稳定的。

  4. in-place:算法使用的额外存储空间是常数级的

一,最基本的冒泡排序——Bubble Sort。

     public void swap(int[] data, int i, int j) { if (i != j) {
        data[i] = data[i] + data[j];
        data[j] = data[i] - data[j];
        data[i] = data[i] - data[j];
    }
}

 

二,冒泡排序(递增)

冒泡排序,是所有排序中最简单的一种,也是效率最低的一种,时间复杂度O(n2),空间复杂度O(n)。冒泡排序没有改变原始元素的相对位置,因此是稳定的排序。

 

     public void bubble_sort(int[] data) {
    for (int i = 0; i < data.length; i++) {
        for (int j = 0; j < data.length; j++) {
            if (data[j] > data[j + 1]) {
                swap(data, j, j + 1);
            }
        }
    }
}

 

三,插入排序(递增)

插入排序也是一种比较简单的排序方法,它的基本原理就好似我们打牌过程中摸牌理牌那一环,当你摸到一张牌后将其插入到合适的位置。

插入排序首先定位一个数(一般从第二个开始),将这个数依次与位于它之前的数进行比较,经过一轮比较,找到它在这些数中适当的位置。然后定位下一个数,再找到合适的为止,依次进行直到最后一个数。

例如(5 2 1 4 3),黑体为进行交换的两数。

  • 第一轮:

    2 5 1 4 3)

  • 第二轮:

    (2 1 5 4 3)

    1 2 5 4 3)

  • 第三轮:

    (1 2 4 5 3)

    (1 2 4 5 3)

    (1 2 4 5 3)

  • 第四轮:

    (1 2 4 3 5

    (1 2 3 4 5)

    (1 2 3 4 5)

    (1 2 3 4 5)排序完成

public void insertion_sort(int[] data) {
    int key = 0;
    int j = 0;
    for (int i = 1; i < data.length; i++) {
        key = data[i];
        j = i - 1;
        while (j >= 0 && data[j] > key) {
            swap(data, j, j + 1);
            j = j - 1;
        }
    }
}

排序插入在数据集较大的时候效率会变得恨低,但是它易于实现,处理小型数据集时效率较高,同时也是稳定的,in-place的,它的时间复杂度是O(n2),空间复杂度是O(n)。

 

四,选择排序

选择排序的工作原理

  1. 找到数据集中的最小元素

  2. 将最小元素与未排序声誉元素的第一个元素交换

  3. 对剩余元素进行以上步骤

它的时间复杂度是O(n2),空间复杂度是O(n),同插入排序类似,它也不适用于大数据集。但是它易于实现,也是一种in-place的排序算法。对于稳定性:简易实现是不稳定的,例如(3 5 5 2),在第二轮中第二个五会被认为是最小的,然后同第一个五进行交换。

public void selection_sort(int[] data) {
    int minimum = 0;
    for (int i = 0; i < data.length - 1; i++) {
        minimum = i;
        for (int j = i + 1; j < data.length; j++) {
            if (data[j] < data[minimum]) {
                minimum = j;
            }
        }
        swap(data, i, minimum);
    }
}

五,ELFHash

public int ELFHash(String str, int number) {
    int hash = 0;
    long x = 0L;
    char[] array = str.toCharArray();
    for (int i = 0; i < array.length; i++) {
        hash = (hash << 4) + array[i];
        if ((x = (hash & 0xF0000000L)) != 0) {
            hash ^= (x >> 24);
            hash &= ~x;
        }
    }
    int result = (hash & 0x7FFFFFFF) % number;
    return result;
}

六,快速排序

快速排序的步骤:

  1. 从数组中选出一个中枢数(pivot)

  2. 重新排列该数组,让数组中比该数小的数都排在该数的前面,比该数大的数都排在该数的后面。经过这次排序,该数处于其最终为止,并将原数组分为两个子数组(大于它的数组和小于它的数组),这就是分段的过程。

  3. 递归的排列各个子数组,直至最后整个数组排序完成。

快速排序的平均时间复杂度为O(nlogn),空间复杂度依据各种实现方式有所不同。

 

public int partition(int[] data, int left, int right, int pivotIndex) {
    int privotValue = data[pivotIndex];
    swap(data, pivotIndex, right); // Move pivot to end
    int storeIndex = left;
    for (int i = left; i < right; i++) {
         if (data[i] <= privotValue) {
            swap(data, i, storeIndex);
            storeIndex = storeIndex + 1;
         }
    }
    swap(data, storeIndex, right); // Move pivot to its final place
    return storeIndex;
}

 

public void quick_sort(int[] data, int left, int right) {
    if (right > left) {
        int pivotIndex = left;
        int pivotNewIndex = partition(data, left, right, pivotIndex);
        quick_sort(data, index, pivotNewIndex - 1);
        quick_sort(data, pivotNewIndex + 1, right);
    }
}

 

七,归并排序

归并排序是一种基于比较的排序算法,在多数的实现方法中它是稳定的。归并排序可是由计算机祖师级人物——冯诺依曼提出的哦。

归并排序的过程:

  1. 如果数据链表的长度为0或1,则返回

  2. 将原始数据链表对半分成两个子链表

  3. 对每个子链表递归的调用合并排序进行排序

  4. 合并两个子链表使其成为一个排序完成的链表

归并排序的时间复杂度为O(nlogn),空间复杂度为O(n)。

public List<Integer> mergesort(List<Integer> data) {
    if (data.size() <= 1) {
        return data;
    }
    int middle = data.size() / 2;

List<Integer> left = new ArrayList<Integer>();
    List<Integer> right = new ArrayList<Integer>();
    for (int i = 0; i < middle; i++) {
        left.add(data.get(i));
    }
    for (int i = middle; i < data.size(); i++) {
        right.add(data.get(i));
    }
    left = mergesort(left);
    right = mergesort(right);
    List<Integer> result = merge(left, right);
    return result;
}

public List<Integer> merge(List<Integer> left, List<Integer> right) {
    List<Integer> result = new ArrayList<Integer>();
    while (left.size() > 0 && right.size() > 0) {
        if (((Integer)left.get(0)).intValue() <= ((Integer)right.get(0)).intValue()) {
            result.add(left.get(0));
            left.remove(0);
        } else {
            result.add(right.get(0));
            right.remove(0);
        }
    }
    if (left.size() > 0) {
        for (Iterator<Integer> iter = left.iterator(); iter.hasNext();) {
            result.add(iter.next());
        }
    }
    if (right.size() > 0) {
        for (Iterator<Integer> iter = right.iterator(); iter.hasNext();) {
            result.add(iter.next());
        }
    }
    return result;
}

八,堆排序

堆排序是一种基于比较的排序算法,它比实现的较好的快速排序慢一些,但是它的平均时间复杂度为O(nlogn),空间复杂度为O(n),它是一种in-place的算法,但是确实不稳定的排序算法。

最大堆和最小堆的定义:

根结点(亦称为堆顶)的关键字是堆里所有节点关键字中最小者的堆成为最小堆。

根结点(亦称为堆顶)的关键字是堆里所有节点关键字中最大者的堆成为最大堆。

P.S.:

堆中任一子树亦是堆。本文讨论的堆实际上是二插堆(Binary Heap),类似地可以定义k叉堆。

堆排序的过程:

  1. 根据输入的数据集建立一个最大堆(最小堆)

  2. 进行堆排序,将Root(最大值)与堆的最后一个元素交换

  3. 堆调整,继续维护成为最大堆

  4. 进行步骤2和3,直至排序完成

public void siftDown(int[] data, int start, int end) {
    int root = start;
    while ((2 * root + 1) <= end) {
        int child = root * 2 + 1;
        int (child < end && data[child] < data[child + 1]) {
            child++;
        }
        if (data[root] < data[child]) {
            swap(data, root, child);
            root = child;
        } else {
            break;
        }
    }
}
这段代码是堆排序的核心,对堆中的元素进行调整。简单来说做的工作就是,即针对一个堆点,将其与它孩子中较大的那个进行比较,若大不变,若小与该孩子交换位置,若交换后该堆点(处于原先它孩子的位置)仍有孩子则继续与孩子中较大的那个进行比较,若大不变,若下与该孩子交换位置,调整直至该堆点没有孩子结束。

 

public void heapify(int[] data, int count) {
    int start = (count - 1) /2;
    while (start >= 0) {
        siftDown(data, start, count - 1);
        start = start - 1;
    }
}

这段代码是建堆的过程,找到最后一个有孩子的堆点,对该堆点进行调整,直至调整到Root。

public void heapsort(int[] data, int count) {
    heapify(data, count);
    int end = count - 1;
    while (end > 0) {
        swap(data, 0, end);
        siftDown(data, 0, --end);
    }
}

这段代码解释了堆排序的过程,首先建堆,然后将Root与堆底元素交换,继而调整现有堆中Root(交换后的Root)位置,不断的调整直至遍历完整个堆。


以上内容转自:http://www.family168.com/tutorial/algorithm/html/algorithm-ch-01.html

分享到:
评论

相关推荐

    2024年全国地区高级图像工程师职位薪酬调查报告

    人力资源+大数据+薪酬报告+涨薪调薪,在学习、工作生活中,越来越多的事务都会使用到报告,通常情况下,报告的内容含量大、篇幅较长。那么什么样的薪酬报告才是有效的呢?以下是小编精心整理的调薪申请报告,欢迎大家分享。相信老板看到这样的报告,一定会考虑涨薪的哦。

    迅雷下载,双击就能安装

    迅雷

    Java命令行学生管理系统的项目解析与入门指南

    内容概要:本文介绍了一个基于Java的简单命令行学生管理系统。该项目包含了添加、查看、更新和删除学生的全部功能,并对每个部分的实现进行了详尽展示,包括关键源代码以及操作步骤指引。项目的主干由多个重要文件构成:Student.java 负责定义学生类及其属性访问器方法;StudentManager.java 实现对学生信息的操作处理逻辑,如创建、读取、更新、销毁(CRUD)等;而 Main.java 则用于执行主程序逻辑并初始化StudentManager实例,提供命令行交互环境以供用户执行相应操作。

    one-api本地部署ollama+deepseek-r1

    one-api本地部署ollama+deepseek-r1

    krpanodew,全景编辑器 一键生成全景图和连续前景图并生成场景

    krpanodew,全景编辑器。一键生成全景图和连续前景图并生成场景。

    基于Matlab 2021的两电平拓扑三相桥式逆变并网仿真:双环PI控制、SPWM调制与LCL滤波研究,基于Matlab2021的电压型三相桥式逆变并网仿真研究:双环PI控制、SPWM调制与LCL滤波

    基于Matlab 2021的两电平拓扑三相桥式逆变并网仿真:双环PI控制、SPWM调制与LCL滤波研究,基于Matlab2021的电压型三相桥式逆变并网仿真研究:双环PI控制、SPWM调制与LCL滤波器的应用,电压型三相桥式逆变并网仿真Matlab2021 电路采用两电平拓扑,采用双环PI控制, 变部分加设PLL锁相环, 采用SPWM调制,逆变器输出端加设LCL滤波器,并入电网。 可以得到逆变器输出端为三电平的线电压波形,滤波后可以得到对称三相电压、电流波形。 无需发,联系即可发邮件。 ,三相桥式逆变器;两电平拓扑;双环PI控制;电压型逆变;PLL锁相环;SPWM调制;LCL滤波器;电网并网;线电压波形。,Matlab 2021三相桥式逆变并网仿真:双环PI控制与LCL滤波器应用

    纯电动汽车零部件建模机理与前后向仿真控制策略详解:聚焦BMS、再生制动及电机驱动扭矩策略,纯电动汽车零部件建模机理与前后向仿真控制策略详解:从Cruise到ADVISOR建模实践与能量流解析,纯电动汽

    纯电动汽车零部件建模机理与前后向仿真控制策略详解:聚焦BMS、再生制动及电机驱动扭矩策略,纯电动汽车零部件建模机理与前后向仿真控制策略详解:从Cruise到ADVISOR建模实践与能量流解析,纯电动汽车各零部件建模机理及BMS、再生制动和电机驱动扭矩策略,逻辑清晰公式明晰。 主要从前向和后向仿真两大类分别阐述建模机理和控制策略。 前向模型主要参考Cruise建模及相关文献,后向模型主要参考ADVISOR建模且对其自带的纯电动汽车模型进行注释分析。 现打包,包含文档、参考模型和参考文献等,适合学习纯电动汽车建模机理,整篇文档主要为公式和整车能量流走向 ,关键零部件建模; BMS; 再生制动; 电机驱动扭矩策略; 前向仿真建模; 后向仿真建模; 能量流走向; 公式明晰; 文档参考。,纯电动整车建模与控制策略解析:BMS、再生制动与电机驱动扭矩的深度研究

    情人节html+css源码

    情人节html+css源码

    基于Yolo系列算法的计算机视觉与人工智能目标检测技术研究,基于Yolo系列算法的计算机视觉与人工智能目标检测技术分析,基于yolo系列的目标检测分析,人工智能,计算机视觉 ,基于yolo系列;目标

    基于Yolo系列算法的计算机视觉与人工智能目标检测技术研究,基于Yolo系列算法的计算机视觉与人工智能目标检测技术分析,基于yolo系列的目标检测分析,人工智能,计算机视觉。 ,基于yolo系列;目标检测分析;人工智能;计算机视觉,基于Yolo系列的人工智能计算机视觉目标检测分析

    火车管理系统-基于SSM.zip(毕设&课设&实训&大作业&竞赛&项目)

    项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用,资源为网络商品(电子资料类)基于网络商品和电子资料商品的性质和特征不支持退款,质量优质,放心下载使用

    Epson-L130,需要删除后缀

    Epson_L130,需要删除后缀

    双重搜索算法BAS-SCA融合正余弦算法优化极限学习机ELM:混合改进机制,避免局部最优,提高收敛精度,双重搜索算法BAS-SCA与正余弦算法融合优化极限学习机ELM:避免局部最优的混合改进机制,提高

    双重搜索算法BAS-SCA融合正余弦算法优化极限学习机ELM:混合改进机制,避免局部最优,提高收敛精度,双重搜索算法BAS-SCA与正余弦算法融合优化极限学习机ELM:避免局部最优的混合改进机制,提高收敛精度,融合天牛须算法与正余弦算法的双重搜索算法BAS-SCA优化极限学习机ELM,采用混合改进机制可有效避免搜索陷入局部最优,收敛精度高 ,关键词:融合算法;双重搜索;BAS-SCA;优化;极限学习机ELM;混合改进机制;局部最优;收敛精度高。,双算法融合优化ELM,高效避免局部最优,提高收敛精度

    基于NPC五电平逆变器的并网逆变器PQ控制技术研究-通过功率闭环控制实现精确电网相位锁相环与高效并网功率因数调整,基于双二阶广义积分器的NPC五电平逆变器并网PQ控制技术:功率闭环控制与离散化仿真实

    基于NPC五电平逆变器的并网逆变器PQ控制技术研究——通过功率闭环控制实现精确电网相位锁相环与高效并网功率因数调整,基于双二阶广义积分器的NPC五电平逆变器并网PQ控制技术:功率闭环控制与离散化仿真实现,NPC五电平逆变器。 并网逆变器PQ控制。 通过功率闭环控制,实现并网单位功率因数,即并网电流与网侧电压同相位。 为了得到电网电网相位,采用基于双二阶广义积分器的锁相环,该锁相环可以快速准确无误的得到电网相位。 且在初始阶段,就可以得到电网相位,比Matlab自带的锁相环要快很多。 并网有功设定为50kW,无功设定为0,通过仿真可以看出,很快实现了给定的并网功率。 整个仿真全部离散化,包括采样与控制的离散,控制与采样环节没有使用simulink自带的模块搭建,全部手工搭建。 ,基于上述信息,以下是几个核心关键词: NPC五电平逆变器; 并网逆变器PQ控制; 功率闭环控制; 电网相位; 快速准确锁相环; 离散化仿真; 手工搭建。,离散化控制的五电平逆变器并网策略研究

    双闭环控制的Buck变换器:实现软启动与离散化仿真的完美电压跟随,Buck变换器:双闭环控制与软启动策略,输出电压平稳跟随参考电压,buck变器 采用双闭环控制,外环为电压环,内环为电流环 其中

    双闭环控制的Buck变换器:实现软启动与离散化仿真的完美电压跟随,Buck变换器:双闭环控制与软启动策略,输出电压平稳跟随参考电压,buck变器。 采用双闭环控制,外环为电压环,内环为电流环。 其中,内环采用平均电流采样。 buck变器采用软启动控制,可以使电流不突变。 从仿真图中可以看出,在0.5秒的时间内,完成了软启动,输出电压完美跟随参考电压。 在1秒时,启动加载。 此时,输出电压有微小的变动,但是马上跟随给定参考电压。 整个仿真完全离散化,主电路与控制部分以不同的步长运行,更加贴合实际。 ,buck变换器;双闭环控制;外环电压环;内环电流环;平均电流采样;软启动控制;离散化仿真;主电路;控制部分步长,双闭环控制的Buck变换器:软启动与精确电压跟随的仿真研究

    大宗商品价格指数(CCPI)(2010-2024年).xlsx

    大宗商品价格指数(Commodity Consumer Price Index,简称CCPI)是一个滞后指标,也是通货膨胀的早期预警指标,能反映通货膨胀的程度。它是特定商品按价格加权计算的指数,反映在不同时点上的价格变动情况。 大宗商品价格指数是一个重要的经济指标,能够反映大宗商品市场的整体价格水平和变动趋势,对于经济预测、政策制定和投资决策等方面都具有重要意义。 数据名称:大宗商品价格指数(CCPI) 数据年份:2010-2024年 ## *02、相关数据* 时间、大宗商品价格指数(CCPI):总指数。

    薅羊毛拼团商城小程序源码V2.5.6+前端.zip

    版本号:2.5.6 – 多开版 更新内容: 1.修复核销记录入口显示 2.修复核销记录中店铺显示 3.修改核销记录中的状态显示 4.修复附近商品订单问题 无需更新小程序 版本号:2.5.5 – 多开版 更新内容: 1.修复指定中奖的问题 2.优化提现功能 3.修改商品销售统计 4.修改后台统计页面 5.小程序新增核销记录 6.修复商家抽佣不到账的问题 7.修复机器人参团跟指定中奖数量叠加的问题 需要更新小程序

Global site tag (gtag.js) - Google Analytics