专业IT网络知识平台,分享IT百科知识、生活百科知识解答!

易企推科技
易企推科技

排序方法有哪几种,八种经典排序算法介绍

来源:小易整编  作者:小易  发布时间:2022-12-10 07:45
摘要:算法和数据结构是一个程序员的内功,所以经常在一些笔试中都会要求手写一些简单的排序算法,以此考验面试者的编程水平。下面我就简单介绍八种常见的排...

实现代码:

/** * @author Ye Hongzhi 公众号:java技术爱好者 * @name HeapSort * @date 2020-09-08 23:34 **/public class HeapSort extends BaseSort {    public static void main(String[] args) {        HeapSort sort = new HeapSort();        sort.printNums();    }    @Override    protected void sort(int[] nums) {        if (nums == null || nums.length < 2) {            return;        }        heapSort(nums);    }    private void heapSort(int[] nums) {        if (nums == null || nums.length < 2) {            return;        }        //构建大根堆        createTopHeap(nums);        int size = nums.length;        while (size > 1) {            //大根堆的交换头尾值,固定最大值在末尾            swap(nums, 0, size - 1);            //末尾的索引值往左减1            size--;            //重新构建大根堆            updateHeap(nums, size);        }    }    private void createTopHeap(int[] nums) {        for (int i = 0; i < nums.length; i++) {            //当前插入的索引            int currIndex = i;            //父节点的索引            int parentIndex = (currIndex - 1) / 2;            //如果当前遍历的值比父节点大的话,就交换值。然后继续往上层比较            while (nums[currIndex] > nums[parentIndex]) {                //交换当前遍历的值与父节点的值                swap(nums, currIndex, parentIndex);                //把父节点的索引指向当前遍历的索引                currIndex = parentIndex;                //往上计算父节点索引                parentIndex = (currIndex - 1) / 2;            }        }    }    private void updateHeap(int[] nums, int size) {        int index = 0;        //左节点索引        int left = 2 * index + 1;        //右节点索引        int right = 2 * index + 2;        while (left < size) {            //最大值的索引            int largestIndex;            //如果右节点大于左节点,则最大值索引指向右子节点索引            if (right < size && nums[left] < nums[right]) {                largestIndex = right;            } else {                largestIndex = left;            }            //如果父节点大于最大值,则把父节点索引指向最大值索引            if (nums[index] > nums[largestIndex]) {                largestIndex = index;            }            //如果父节点索引指向最大值索引,证明已经是大根堆,退出循环            if (largestIndex == index) {                break;            }            //如果不是大根堆,则交换父节点的值            swap(nums, largestIndex, index);            //把最大值的索引变成父节点索引            index = largestIndex;            //重新计算左节点索引            left = 2 * index + 1;            //重新计算右节点索引            right = 2 * index + 2;        }    }    private void swap(int[] nums, int i, int j) {        int temp = nums[i];        nums[i] = nums[j];        nums[j] = temp;    }}//10万个数的数组,耗时:38毫秒

算法复杂度:O(nlogn)算法空间复杂度:O(1)算法稳定性:不稳定

八、桶排序

思路:

  1. 找出最大值,最小值。

  2. 根据数组的长度,创建出若干个桶。

  3. 遍历数组的元素,根据元素的值放入到对应的桶中。

  4. 对每个桶的元素进行排序(可使用快排,插入排序等)。

  5. 按顺序合并每个桶的元素,排序完成。

对于数组中的元素分布均匀的情况,排序效率较高。相反的,如果分布不均匀,则会导致大部分的数落入到同一个桶中,使效率降低。

动画演示(来源于五分钟学算法,侵删):

实现代码:

/** * @author Ye Hongzhi 公众号:java技术爱好者 * @name BucketSort * @date 2020-09-08 23:37 **/public class BucketSort extends BaseSort {    public static void main(String[] args) {        BucketSort sort = new BucketSort();        sort.printNums();    }    @Override    protected void sort(int[] nums) {        if (nums == null || nums.length < 2) {            return;        }        bucketSort(nums);    }    public void bucketSort(int[] nums) {        if (nums == null || nums.length < 2) {            return;        }        //找出最大值,最小值        int max = Integer.MIN_VALUE;        int min = Integer.MAX_VALUE;        for (int num : nums) {            min = Math.min(min, num);            max = Math.max(max, num);        }        int length = nums.length;        //桶的数量        int bucketCount = (max - min) / length + 1;        int[][] bucketArrays = new int[bucketCount][];        //遍历数组,放入桶内        for (int i = 0; i < length; i++) {            //找到桶的下标            int index = (nums[i] - min) / length;            //添加到指定下标的桶里,并且使用插入排序排序            bucketArrays[index] = insertSortArrays(bucketArrays[index], nums[i]);        }        int k = 0;        //合并全部桶的        for (int[] bucketArray : bucketArrays) {            if (bucketArray == null || bucketArray.length == 0) {                continue;            }            for (int i : bucketArray) {                //把值放回到nums数组中                nums[k++] = i;            }        }    }    //每个桶使用插入排序进行排序    private int[] insertSortArrays(int[] arr, int num) {        if (arr == null || arr.length == 0) {            return new int[]{num};        }        //创建一个temp数组,长度是arr数组的长度+1        int[] temp = new int[arr.length + 1];        //把传进来的arr数组,复制到temp数组        for (int i = 0; i < arr.length; i++) {            temp[i] = arr[i];        }        //找到一个位置,插入,形成新的有序的数组        int i;        for (i = temp.length - 2; i >= 0 && temp[i] > num; i--) {            temp[i + 1] = temp[i];        }        //插入需要添加的值        temp[i + 1] = num;        //返回        return temp;    }}//10万个数的数组,耗时:8750毫秒

算法复杂度:O(M+N)

算法空间复杂度:O(M+N)

算法稳定性:稳定(取决于桶内的排序算法,这里使用的是插入排序所以是稳定的)。

总结

动画演示来源于算法学习网站

讲完这些排序算法后,可能有人会问学这些排序算法有什么用呢,难道就为了应付笔试面试?平时开发也没用得上这些。

我觉得我们应该换个角度来看,比如高中时我们学物理,化学,数学,那么多公式定理,现在也没怎么用得上,但是高中课本为什么要教这些呢?

我的理解是:第一,普及一些常识性的问题。第二,锻炼思维,提高解决问题的能力。第三,为了区分人才。

回到学排序算法有什么用的问题上,实际上也一样。这些最基本的排序算法就是一些常识性的问题,作为开发者应该了解掌握。同时也锻炼了编程思维,其中包含有双指针,分治,递归等等的思想。最后在面试中体现出来的就是人才的划分,懂得这些基本的排序算法当然要比不懂的人要更有竞争力。

建议大家看完之后,能找时间动手写一下,加深理解。


本文地址:网络知识频道 https://www.hkm168.com/jiqiao/868867_3.html,易企推百科一个免费的知识分享平台,本站部分文章来网络分享,本着互联网分享的精神,如有涉及到您的权益,请联系我们删除,谢谢!

共3页 1 2 3 当前是最后一页

网络知识
小编:小易整编
相关文章相关阅读
  • php怎么实现对字符串的排序

    php怎么实现对字符串的排序

    实现步骤:1、利用str_split()函数将字符串转为字符数组,语法“str_split(字符串)”;2、使用asort()或arsort()函数来对字符数组进行升序排序或降序排序,语法“asort(字符数组)”或“arsort(字符数组...

  • 什么是结构化程序设计

    什么是结构化程序设计

    结构化程序设计是一种使程序更加清晰、易于理解和维护的编程方法论。通过将程序划分为不同的模块,并使用控制结构来组织这些模块,结构化程序设计使程序的开发和维护更加高效和可靠,无论是初学者还是有经验的开发者,都应该掌握结构化程序设计的基本原理和技...

  • c语言程序的基本单位是什么

    c语言程序的基本单位是什么

    c语言程序的基本单位是函数,函数是c程序的基本组成单位,一个c语言程序中仅有一个main函数,除main函数之外可以有若干个其它的函数,每个函数实现某一特定的操作。推荐:《C语言教程》C语言程序是由函数构成的,函数是C程序的基本组成单位,一...

  • 什么是指令,什么是程序?

    什么是指令,什么是程序?

    指令是计算机能实现的基本操作,是指挥机器工作的指示和命令,指令均为二进制数形式;指令由操作码和地址码组成,操作码告诉计算机执行什么操作,地址码告诉计算机到哪个存储单元地址中读取参与操作的数据。而程序是若干指令或命令的集合。本教程操作环境:w...

  • 网页中最基本的元素是什么

    网页中最基本的元素是什么

    网页中最基本的元素是“文字和图像”。网页是构成网站的基本元素,是承载各种网站应用的平台;而文字与图像是构成一个网页的两个最基本的元素,文字就是网页的内容,图像就是网页的美观;除此之外,网页的元素还包括动画、音乐、视频等等。网页是构成网站的...

  • c语言运算符的优先级顺序怎么排序

    c语言运算符的优先级顺序怎么排序

    c语言运算符的优先级顺序是括号运算符>一元运算符>算术运算符>移位运算符>关系运算符>位运算符>逻辑运算符>赋值运算符>逗号运算符。理解并正确使用运算符的优先级是c语言编程的关键之一,它有助于......

  • 如何在uniapp中使用微信小程序的API接口

    如何在uniapp中使用微信小程序的API接口

    如何在uniapp中使用微信小程序的API接口随着微信小程序的流行,越来越多的开发者希望将微信小程序的功能应用到其他平台上。而uniapp作为一个跨平台开发框架,为开发者提供了一个方便的方式来实现这一目标。本文将详细介绍在uniapp中如何...

  • 怎么自学成为一个程序员

    怎么自学成为一个程序员

    众所周知程序员是21世纪比较吃香的工作。程序员工资高还不需要和复杂的社会打交道。那么作为一个零基础,什么都不懂的人该怎么成为一名程序员?当程序员需要学什么?下面就来分析下。零基础的我该如何学习?如果想做一个程序员,在没有基础的情况下,买书自...

  • 周排行
  • 月排行
  • 年排行

精彩推荐