排序算法总结(精简详细)

排序算法杂记 1、精简排序,即一对数字不进行两次和两次以上的比较,以下是“精简排序”的是正确答案: A B A、插入排序 B、归并排序 C、选择排序 D、堆排序插入排序:前面是有序的,后面的每一个元素与前面有序的元素比较,比较过的就是有序的了,不会再比较一次,例如:3 2 1 5 第一趟:【2,3,1,5】,2和3比较,3后移;第二趟:【1,2,3,5】,1和2,1和3比较,而2, 阅读详情

// 插入排序:顺序地把待排序的数据按关键字大小插入到已排序的子集合的适当位置

// 插入排序对于部分有序数组和小规模数组特别高效

void insertSort(int[] A, int n) {

        for (int i = 1; i < n; i++) {
            int tmp = A[i];
            int j = i;
            for (; j > 0 && A[j - 1] > tmp; j--) {
                A[j] = A[j - 1];
            }
            A[j] = tmp;
        }
    }


// 希尔排序:把待排序的数据元素分成若干个小组,对同一组内使用插入法排序

// 距离逐渐减小,直到只比较相邻元素的最后一趟为止,因此也称缩小增量排序

// 希尔排序的运行时间达不到平方级别

void shellSort(int[] A, int n) {
        for (int increment = n / 2; increment > 0; increment /= 2) {
            for (int i = increment; i < n; i++) {
                int tmp = A[i];
                int j = i;
                for (; j >= increment; j -= increment) {
                    if (tmp < A[j - increment]) {
                        A[j] = A[j - increment];
                    } else {
                        break;
                    }
                }
                A[j] = tmp;
            }
        }
    }


// 选择排序:维护一个已排序集合,从未排序集合中选择最小值与第一个元素交换

// 然后增大已排序集合范围,直到最后一个元素

// 它的运行时间与输入无关

void selectSort(int[] A, int n) {
        for (int i = 0; i < n - 1; i++) {
            int small = i;
            for (int j = i + 1; j < n; j++) {
                if (A[j] < A[small]) {
                    small = j;
                }
            }
            if (small != i) {
                swap(A, i, small);
            }
        }
    }


// 冒泡排序:将大元素依次沉底,然后缩小数据元素范围.有些待排序元素序列已经基本有序

// 优化:可以设一个flag变量标记本次是否有交换动作,提前结束排序过程

 void bubbleSort(int[] A, int n) {
        boolean flag = true;
        for (int i = 1; i < n && flag; i++) {
            flag = false;
            for (int j = 0; j < n - i; j++) {
                if (A[j] > A[j + 1]) {
                    flag = true;
                    swap(A, j, j + 1);
                }
            }
        }
    }


// 归并排序:思想是将数组分成两部分,分别进行排序,然后归并起来

static int[] aux;
    public void merge(int[] A, int lo, int mid, int hi) {
        int i = lo, j = mid + 1;
        for (int k = lo; k <= hi; k++) {
            aux[k] = A[k];
        }
        for (int k = lo; k <= hi; k++) {
            if (i > mid) {
                A[k] = aux[j++];
            } else if (j > hi) {
                A[k] = aux[i++];
            } else if (aux[i] < A[j]) {
                A[k] = aux[i++];
            } else {
                A[k] = aux[j++];
            }
        }
    }
    // 自顶向下
    public void  mergeSort(int[] A, int n) {
        aux = new int[n];
        mergeSort(A, 0, n - 1);
    }
    public void  mergeSort(int[] A, int lo, int hi) {
        if (hi <= lo) return;
        int mid = lo + (hi - lo) / 2;
        mergeSort(A, lo, mid);
        mergeSort(A, mid + 1, hi);
        merge(A, lo, mid, hi);
    }


// 快速排序:通过一个切分元素将数组分为两个子数组,左子数组小于等于切分元素

// 右子数组大于等于切分元素,将这两个子数组排序也就将整个数组排序了

public void quickSort(int[] A, int n) {
        quickSort(A, 0, n - 1);
    }
    public void quickSort(int[] A, int lo, int hi) {
        if (hi <= lo) return;
        int j = partition(A, lo, hi);
        quickSort(A, lo, j - 1);
        quickSort(A, j + 1, hi);
    }
    /*取 a[lo] 作为切分元素,然后从数组的左端向右扫描直到找到第一个大于等于它的元素
    再从数组的右端向左扫描找到第一个小于等于它的元素,交换这两个元素,并不断继续这个过程
    就可以保证左指针的左侧元素都不大于切分元素,右指针 j 的右侧元素都不小于切分元素
    当两个指针相遇时,将切分元素 a[lo] 和左子数组最右侧的元素 a[j] 交换然后返回 j 即可*/
    public int partition(int[] A, int lo, int hi) {
        int i = lo, j = hi + 1;
        int v = A[lo];
        while (true) {
            while (A[++i] < v) {
                if (i == hi) {
                    break;
                }
            }
            while (A[--j] > v) {
                if (j == lo) {
                    break;
                }
            }
            if (i >= j) break;

            swap(A, i, j);
        }
        swap(A, lo, j);
        return j;
    }


堆排序:由于堆可以很容易得到最大的元素并删除它,不断地进行这种操作可以得到一个递减序列

如果把最大元素和当前堆中数组的最后一个元素交换位置,并且不删除它,那么就可以得到一个从尾到头的递减序列,从正向来看就是一个递增序列

因此很容易使用堆来进行排序,并且堆排序是原地排序,不占用额外空间。

堆排序要分两个阶段,第一个阶段是把无序数组建立一个堆

第二个阶段是交换最大元素和当前堆的数组最后一个元素,并且进行下沉操作维持堆的有序状态

无序数组建立堆最直接的方法是从左到右遍历数组,然后进行上浮操作

一个更高效的方法是从右至左进行下沉操作,如果一个节点的两个节点都已经是堆有序

那么进行下沉操作可以使得这个节点为根节点的堆有序。叶子节点不需要进行下沉操作

因此可以忽略叶子节点的元素,因此只需要遍历一半的元素即可

分析

一个堆的高度为 lgN,因此在堆中插入元素和删除最大元素的复杂度都为 lgN。

对于堆排序,由于要对 N 个节点进行下沉操作,因此复杂度为 NlgN。

堆排序时一种原地排序,没有利用额外的空间

现代操作系统很少使用堆排序,因为它无法利用缓存,也就是数组元素很少和相邻的元素进行比较

int leftChild(int i) {
        return 2 * i + 1;
    }
    void sink(int[] A, int i, int N) {
        int child;
        int tmp = A[i];
        for (; leftChild(i) < N; i = child) {
            child = leftChild(i);
            if (child != N - 1 && A[child + 1] > A[child]) {
                child++;
            }
            if (tmp < A[child]) {
                A[i] = A[child];
            } else {
                break;
            }
        }
        A[i] = tmp;

    }
    public void heapSort(int[] A, int n) {
        for (int i = n / 2; i >= 0; i--) {
            sink(A, i, n); // buildHeap
        }
        for (int i = n - 1; i > 0; i--) {
            swap(A, 0, i); // delMax
            sink(A, 0, i);
        }
    }


// 基数排序

基本思想:m位 d进制整数, 不足m 位的关键字高位补0;设置d 个桶,按关键字的最低位依次把元素放入桶中,此为第一次基数排序; 然后依次按次低位,直到 最高位. 经过 m次基数排序后所有元素已经有序.

public void radixSort(int[] A, int n) {
        if (A == null || n < 1) {
            return;
        }
        //首先确定排序的趟数;
        int max = A[0];
        for (int i = 1; i < n; i++) {
            if (A[i] > max) {
                max = A[i];
            }
        }

        int time = 0;
        //判断位数;
        while (max > 0) {
            max /= 10;
            time++;
        }

        //建立10个桶;
        List<ArrayList<Integer>> queue = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            ArrayList<Integer> queue1 = new ArrayList<Integer>();
            queue.add(queue1);
        }

        //进行time次分配和收集;
        for (int i = 0; i < time; i++) {
            //分配数组元素;
            for (int j = 0; j < n; j++) {
                //得到数字的第time+1位数;
                int x = A[j] % (int) Math.pow(10, i + 1) / (int) Math.pow(10, i);
                ArrayList<Integer> queue2 = queue.get(x);
                queue2.add(A[j]);
                queue.set(x, queue2);
            }

            int count = 0;//元素计数器;
            //收集队列元素;
            for (int k = 0; k < 10; k++) {
                while (queue.get(k).size() > 0) {
                    ArrayList<Integer> queue3 = queue.get(k);
                    A[count] = queue3.get(0);
                    queue3.remove(0);
                    count++;
                }
            }

        }
    }


// 计数排序

public int[] countingSort(int[] A, int n) {
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < n; i++) {
            if (A[i] > max) {
                max = A[i];
            }
        }
        int[] count = new int[max + 1];
        for (int i = 0; i < n; i++) {
            count[A[i]]++;
        }
        int index = 0;
        for (int i = 0; i < max + 1; i++) {
            while (count[i] != 0) {
                A[index++] = i;
                count[i]--;
            }
        }
        return A;
    }

【数据结构】七大排序算法(超详细) 本文详细介绍了数据结构中的七大排序算法 阅读详情

相关推荐

十大经典排序算法Java实现(代码详细注释)

1.冒泡排序 2.选择排序 3.插入排序 4.快速排序 5…希尔排序 6.计数排序 7.归并排序 8. 基数排序 9.堆排序 10.桶排序

致虚极POLE守静笃 3104

十大排序算法极简汇总篇

用一张图汇总了10大排序算法的性质如果你是复习/学习十大排序算法,一定要自己不看示例代码手动实现一遍,一定要自己不看示例代码手动实现一遍,一定要自己不看示例代码手动实现一遍。

帅地 741

基于LSTM的多变量温度预测(python从入门到入坑)

基于LSTM的多变量温度预测(python) ——我保证他能够运行,而且结果能够让你满意(如果你和我一样都是一个新手的话) 这里写目录标题基于LSTM的多变量温度预测(python)——我保证他能够运行,而且结果能够让你满意(如果你和我一样都是一个新手的话)一、我为什么要写这些?二、具体做了什么?三、源代码切块加注释,恳请批评指正(●’◡’●)ノ 一、我为什么要写这些? 因为让人抓狂的课程大作业,我小组选择了一个多变量预测方面的课题,在我这个大三基本上还没接触过Python数据处理,甚至对神经网络什么的都

代码之狐的博客 1万+

最简洁的排序算法总结

排序算法简述 1、插入排序 将第一个和第二个元素排好序,然后将第3个元素插入到已经排好序的元素中,依次类推(插入排序最好的情况就是数组已经有序了) 2、希尔排序 因为插入排序每次只能操作一个元素,效率低。元素个数N,取奇数k=N/2,将下标差值为k的数分为一组(一组元素个数看总元素个数决定),在组内构成有序序列,再取k=k/2,将下标差值为k的数分为一组,构成有序序列,直到k=1,然后再进行直接插...

XBlog 1435

ANSYS 有限元分析 支架拓扑优化设计 分析过程及常见问题解决

1.确定分析类型,所用模块包括两种 static structural Topology Optimization。3.通过草图建立几何模型,建好的几何模型如图1所示。2.工程材料采用默认的Q235。

m0_68737530的博客 1966

6.5 构网型储能系统的协同控制策略

本文系统阐述了构网型储能系统的协同控制策略,重点分析了多机组群协同运行面临的功率分配不均、动态响应失配等挑战。研究提出了改进型下垂控制与虚拟阻抗法、基于一致性算法的分布式协同控制等解决方案,探讨了构网型储能与同步发电机在惯性响应、一次调频等方面的协同机制,以及与跟网型电源在电压支撑、阻抗重塑等方面的互补作用。文章构建了分层控制架构,为实现多类型电源的全局优化运行提供了技术路径,对提升高比例新能源电力系统的稳定性具有重要意义。

技术工作者 1002

7种常用简单排序算法

7种简单排序算法小结 假设所有的排序都是从小到大进行的 问题:给定n个元素,输出这n个元素从小到大的顺序(第一行读入一个n,接下来读入n个元素,每个元素不超过100)(n < 100) 样例输入: 6 21 25 49 28 16 8 样例输出: 8 16 21 25 28 49 **稳定性描述:**假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相...

Psychosocial的博客 1290

JavaScript性能优化:全链路性能优化策略

JavaScript性能优化是提升Web应用质量的核心要素,直接影响用户体验与业务成果。研究表明,页面加载延迟1秒可能导致转化率下降7%。高效的JavaScript执行能减少主线程阻塞,避免动画卡顿或操作延迟,尤其在移动端低性能设备上更为关键。优化内存管理与减少冗余计算可降低浏览器资源消耗,防止因内存泄漏导致的崩溃,提升应用稳定性。在竞争激烈的互联网环境中,性能优势已成为产品差异化的关键因素,直接影响用户留存与商业价值。因此,性能优化应作为开发全周期的核心实践,而非事后补救措施。

weixin_49707375的博客 1270

几种常见的简单排序算法

几种常见的简单排序:冒泡排序,选择排序,插入排序,快速排序,sort排序

skycol的博客 2506

Codesys 3.5报警功能配置保姆级教程:从变量定义到确认方式(含REF/ACK详解)

本文详细介绍了Codesys 3.5报警功能的配置流程,从变量定义到确认方式的选择,特别解析了REF和ACK两种确认方式的底层逻辑。通过实战案例和代码示例,帮助工程师快速掌握报警系统的搭建与调试技巧,提升工业自动化项目的可靠性。

weixin_29245767的博客 458

【Com通信】Com模块的事件帧发送及周期报文的快慢发送机制

Com模块的事件帧发送及周期报文的快慢发送机制

qq_36056498的博客 2335

冒泡排序(普通版+小升级精简版)

冒泡排序: 一种排序的方式,对要进行排序的数据中相邻的数据进行两两比较,将较大的数据放在后面,依次对所有的数据进行操作,直至所有的数据按要求完成排序。 首先创建一个使用冒泡排序的类。在创建一个主函数 在主函数下面创建一个字符串排序方法,这里是通过StringBuilder创建对象完成 public static String arrayToString(int[] arr) { StringBuffer sb =new StringBuffer(); sb.appe.

qq_65645316的博客 293

微信小程序视频内容服务类目审核不过?绕过审核的两种思路!

虽然不推荐绕过官方审核,但在实际项目中,总有一些特殊情况:比如,最近开发的小程序涉及视频播放,提交审核时,被官方要求补充“教育服务 - 在线视频课程”类目。但我们的内容只是车辆使用介绍,并非教育课程,无法提供相应资质。该怎么办?很多开发者发现,小程序开发不是最难的,审核才是最难的。 微信为了规避法律风险,要求某些功能必须提供资质。例如:然而,并不是所有公司都能轻松申请到这些资质,甚至有些资质根本不适用于我们的业务,导致审核卡住,无法上线。就像我遇到的这个问题,官方要求我们补充“在线视频课程”类目,但实际业务

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 3245

排序算法的详解和分析对比(详细讲解)

排序算法各式各样,每种排序算法的思想也大同小异。读者应该深度了解每种算法的基本思想、排序每一步过程细节和每种排序的特性,看到特定的序列,应该立马想到最适合的排序方法。一些简单的排序算法中,虽然效率不高,但是在低数量规模情况下,就比如一万数量级以下,一般运行时间还能可以被人们所接受,零点几秒左右很难被察觉出来。但是如果到了十万数量级,排序就需要非常久的时间,可能会导致我们一些系统会出现误差,从而引起巨大的麻烦和问题。

gongjunbox的博客 9593

YOLOv5 自定义模型 Android 部署完整指南

本文详细介绍了将YOLOv5模型部署到Android设备的完整流程,包含三个核心部分:首先验证官方模型测试,确保基础环境配置正确;随后进行模型转换,从PyTorch导出ONNX格式并优化,再转换为NCNN格式;最后在Android项目中集成自定义模型,包括文件替换、参数修改和代码适配。教程基于YOLOv5 6.1版本,使用NCNN框架进行移动端推理,涵盖了常见问题解决方案和关键配置要点,为开发者提供了从训练到部署的完整技术路线。

FJN110的博客 592

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

排序算法详细讲解(超酷)

排序算法作为数据结构中重要的部分,是必须要掌握的知识之一。 目录 前言 一、插入类排序 1.直接插入排序 2.折半插入排序 3.希尔排序 二、交换类排序 1.冒泡排序(相邻比序法) 2.快速排序 三、选择类排序 1.简单选择排序 2.树形选择排序 3.堆排序 四、归并排序 五、分配类排序 1.多关键字排序 2.链式基数排序 3.计数排序 总结 前言 在进行数据处理时,经常需要对数据进行查找,为了查的更快,通常要求数据有序排列。根据排序时......

qq_51419787的博客 1万+

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

排序算法详细总结

排序算法详细总结

世界那么大,我想去看看~【随心更新,看世界去了😄】 1639

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

最新十大排序算法详细讲解,以及各种应用场景

十大排序算法汇总 比较和非比较的区别 常见的快速排序、归并排序、堆排序、冒泡排序等属于比较排序。在排序的最终结果里,元素之间的次序依赖于它们之间的比较。每个数都必须和其他数进行比较,才能确定自己的位置。 在冒泡排序之类的排序中,问题规模为n,又因为需要比较n次,所以平均时间复杂度为O(n²)。在归并排序、快速排序之类的排序中,问题规模通过分治法消减为logN次,所以时间复杂度平均O(nlogn)...

小猪向前冲 1万+

【超详细】八大排序算法的各项比较以及各自特点

千万不要错过这篇,不然你就亏大发了。 八大排序,各显神通。 前言 一、排序的概念 二、各算法特点 1.直接选择排序 2.堆排序 3.直接插入排序 4.希尔排序 5.冒泡排序 6.快速排序 7.归并排序 8.基数排序 总结 前言 排序是计算机程序设计中一个非常重要的操作,它将一个数据元素(或记录)的任意序列重新排列成一个按关键字有序的序列。在有序的序列中查找元素的效率很高,(例如,折半查找法的平均查找长度为log2(n+1)−1log2(n+1...

qq_45615577的博客 3万+

C语言八大排序算法【详细 代码+图文】

C语言八大排序算法 辅助方法代码 void ShowArr(int* arr, int len) //显示数组 { for (int i = 0; i < len; ++i) { printf("%d ", arr[i]); } printf("\n"); } bool IsSort(int* arr, int len) //判断数据是否有序,从小到大 { for (int i = 0; i < len - 1; ++i) { if (arr[i] > arr[

qq_43579888的博客 1万+

【精简】排序算法总结

文章目录选择排序冒泡排序插入排序快速排序归并排序堆排序完全二叉树 选择排序 遍历数组记录最小值下标,与第一项依次交换。 for(int i=1;i<n;i++){ int count=i; for(int j=i+1;j<=n;j++){ if(num[count]>num[j])count=j; } swap(num[count],num[i]); } 冒泡排序 将大气泡换到后面 for(int i=n;i>=1;i--){ for(int j=1;j<i;j

zhimeng_LQ的博客 765

常见排序算法详细总结

常见排序算法详细总结前言排序算法的特性基于比较的排序和非比较的排序时间复杂度排序算法时间复杂度的简略证明空间复杂度排序算法的稳定性代码实现冒泡排序选择排序插入排序希尔排序归并排序快速排序堆排序二叉搜索树排序桶排序计数排序基数排序TimSort参考 前言 排序算法在计算机科学入门课程中很普遍,同时在面试和笔试中也经常涉及到,本文就总结了十二种排序算法供大家学习,当然排序算法有很多很多,本文只总结了常见的和经典的几种。 排序算法的特性 首先对于一个排序算法我们要做的不单单是搞懂原理和代码,更重要的是知道如何去评

LYB的博客 934

排序算法详细介绍对比及备考建议

全网最全排序算法介绍

qq_47898999的博客 1376

排序算法 —— 直接插入排序(图文超详细)

java 实现七大排序算法中的直接插入排序

超烦豆先森 1万+

各种排序算法的详细总结与比较

最近开始找工作了,总结一些基本问题供复习。 排序算法可以说是一项基本功,解决实际问题中经常遇到,针对实际数据的特点选择合适的排序算法可以使程序获得更高的效率,有时候排序的稳定性还是实际问题中必须考虑的,这篇博客对常见的排序算法进行整理,包括:插入排序、选择排序、冒泡排序、快速排序、堆排序、归并排序、希尔排序、二叉树排序、计数排序、桶排序、基数排序。 比较排序和非比较排序 ...

这里记录着我一点一滴的进步 3万+
上一篇: Linux学习笔记(一)----基本bash shell命令
下一篇: Linux学习笔记(二)----更多bash shell命令
普通网友
博客等级 码龄9年 489粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值