您当前的位置:首页 > 电脑百科 > 程序开发 > 算法

冒泡,选择,插入,希尔,归并,快速排序大合集,面试收藏必备

时间:2020-05-03 10:42:29  来源:  作者:

在很多大厂的面试中,算法是最基本的要求,像基础的算法,冒泡,选择,插入等,基本上都会问到。

很多同学往往忽略了其重要程度,只注重编程语言,小编并不建议这样子,今天我们来梳理一下算法,汇总一下面试的一些基础算法。

冒泡排序

原理:每次冒泡排序操作都会将相邻的两个元素进行比较,看是否满足大小关系要求,如果不满足,就交换这两个相邻元素的次序,一次冒泡至少让一个元素移动到它应该排列的位置,重复N次,就完成了冒泡排序。

冒泡,选择,插入,希尔,归并,快速排序大合集,面试收藏必备

 

代码实现

 

/**
     * 冒泡算法
     * @author:溪云阁
     * @date:2020年5月3日
     * 冒泡排序只会操作相邻的两个数据。每次冒泡操作都会对相邻的两个元素进行比较,看是否满足大小关系要求。
     * 如果不满足就让它俩互换。一次冒泡会让至少一个元素移动到它应该在的位置,重复n 次,
     * 就完成了 n 个数据的排序工作。
     */
    public static void bubbleSort(Integer[] arr) {
        // 如果只有一个元素就不用排序了
        if (arr.length <= 1) {
            return;
        } else {
            // 打印排序后的数组
            System.out.println("排序前的数组:" + Arrays.toString(arr));
            for (int i = 0; i < arr.length; ++i) {
                // 提前退出冒泡循环的标志位,即一次比较中没有交换任何元素,这个数组就已经是有序的了
                boolean flag = false;
                // 此处你可能会疑问的j<n-i-1,因为冒泡是把每轮循环中较大的数飘到后面,
                for (int j = 0; j < arr.length - i - 1; ++j) {
                    // 数组下标又是从0开始的,i下标后面已经排序的个数就得多减1,总结就是i增多少,j的循环位置减多少
                    if (arr[j] > arr[j + 1]) {
                        // 即这两个相邻的数是逆序的,交换位置
                        final int temp = arr[j];
                        arr[j] = arr[j + 1];
                        arr[j + 1] = temp;
                        flag = true;
                    }
                }
                if (!flag)
                    // 没有数据交换,数组已经有序,退出排序
                    break;
            }
            // 打印排序后的数组
            System.out.println("排序后的数组:" + Arrays.toString(arr));
        }
    }

 

选择排序

原理:先遍历数组,然后找到一个最大或者最小的元素(这个看需要),把这个元素放到第一个位置,接着在剩余的数组中继续找,找到比第一个大或者小的元素,放到第二个位置,依次这样子做,从而完成排序。

 

冒泡,选择,插入,希尔,归并,快速排序大合集,面试收藏必备

 

代码实现:

 /**
     * 选择排序
     * @author 溪云阁
     * @param arr void
     * 先遍历数组,然后找到一个最大或者最小的元素(这个看需要)
     * 把这个元素放到第一个位置,接着在剩余的数组中继续找
     * 找到比第一个大或者小的元素,放到第二个位置
     * 依次这样子做,从而完成排序。
     */
    public static void selectSort(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            // 用来记录最小值的索引位置,默认值为i
            int minIndex = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] < arr[minIndex]) {
                    // 遍历 i+1~length 的值,找到其中最小值的位置
                    minIndex = j;
                }
            }
            // 交换当前索引 i 和最小值索引 minIndex 两处的值
            if (i != minIndex) {
                final int temp = arr[i];
                arr[i] = arr[minIndex];
                arr[minIndex] = temp;
            }
        }
    }

插入排序

原理:这个比较抽象,但是我来划分来辅助理解

一组无序序列{A1,A2,........An}

先取出A1,然后从A2与A1比较,比较完之后序列状况是{A1,A2}{A3..........An},这时候其中{A1,A2}就变成有序

然后取出A3 ,放到{A1,A2}有序序列合适位置,从而形成{A1,A2,A3}{A4........An}

重复这个过程,直到取出An放入{A1,A2........An-1}有序序列中

 

冒泡,选择,插入,希尔,归并,快速排序大合集,面试收藏必备

 

代码实现:

 /**
     * 插入排序
     * @author 溪云阁
     * @param ins
     * @return int[]
     * 一组无序序列{A1,A2,........An}
     * 先取出A1,然后从A2与A1比较,比较完之后序列状况是{A1,A2}{A3..........An},这时候其中{A1,A2}就变成有序
     * 然后取出A3 ,放到{A1,A2}有序序列合适位置,从而形成{A1,A2,A3}{A4........An}
     * 重复这个过程,直到取出An放入{A1,A2........An-1}有序序列中
     */
    public static int[] insertSort(int[] ins) {
        for (int i = 1; i < ins.length; i++) {
            // 保存每次需要插入的那个数
            final int temp = ins[i];
            int j;
            for (j = i; j > 0 && ins[j - 1] > temp; j--) {
                // 吧大于需要插入的数往后移动。最后不大于temp的数就空出来j
                ins[j] = ins[j - 1];
            }
            // 将需要插入的数放入这个位置
            ins[j] = temp;
        }
        return ins;
    }

希尔排序

原理:希尔排序是插入排序的改进版,它将数组按照约定的数量分成N列,对每一列执行插入排序,接着缩小步长,不断重复这过程,最后整个表就只有一列了。将数组转换至表是为了更好地理解这算法。

 

冒泡,选择,插入,希尔,归并,快速排序大合集,面试收藏必备

 

代码实现:

/**
     * 希尔排序
     * @author 溪云阁
     * @param arrays void
     * 希尔排序是插入排序的改进版,
     * 它将数组按照约定的数量分成N列,对每一列执行插入排序,接着缩小步长
     * 不断重复这过程,最后整个表就只有一列了
     */
    public static void shellSort(int[] arrays) {
        if (arrays == null || arrays.length <= 1) {
            return;
        } else {
            // 增量
            int incrementNum = arrays.length / 2;
            while (incrementNum >= 1) {
                for (int i = 0; i < arrays.length; i++) {
                    // 进行插入排序
                    for (int j = i; j < arrays.length - incrementNum; j = j + incrementNum) {
                        if (arrays[j] > arrays[j + incrementNum]) {
                            final int temple = arrays[j];
                            arrays[j] = arrays[j + incrementNum];
                            arrays[j + incrementNum] = temple;
                        }
                    }
                }
                // 设置新的增量
                incrementNum = incrementNum / 2;
            }
        }
    }

归并排序

原理:归并其实就是分而治之的思想,对于每一个数组,每个递归过程涉及三个步骤
1、分解::把待排序的 n 个元素的序列分解成两个子序列, 每个子序列包括 n/2 个元素.
2、治理::对每个子序列分别调用归并排序MergeSort, 进行递归操作
3、合并:合并两个排好序的子序列,生成排序结果.

 

冒泡,选择,插入,希尔,归并,快速排序大合集,面试收藏必备

 

代码实现:

/**
     * 两路归并算法,两个排好序的子序列合并为一个子序列
     * @author 溪云阁 
     * @param a
     * @param left
     * @param mid
     * @param right void
     */
    public static void merge(int[] a, int left, int mid, int right) {
        // 辅助数组
        final int[] tmp = new int[a.length];
        // p1、p2是检测指针,k是存放指针
        int p1 = left, p2 = mid + 1, k = left;
        while (p1 <= mid && p2 <= right) {
            if (a[p1] <= a[p2])
                tmp[k++] = a[p1++];
            else
                tmp[k++] = a[p2++];
        }
        while (p1 <= mid) {
            // 如果第一个序列未检测完,直接将后面所有元素加到合并的序列中
            tmp[k++] = a[p1++];
        }
        while (p2 <= right) {
            // 同上
            tmp[k++] = a[p2++];
        }
        // 复制回原素组
        for (int i = left; i <= right; i++) {
            a[i] = tmp[i];
        }
    }

    /**
     * 归并排序
     * @author 溪云阁
     * @param a
     * @param start
     * @param end void
     */
    public static void mergeSort(int[] a, int start, int end) {
        // 当子序列中只有一个元素时结束递归
        if (start < end) {
            // 划分子序列
            final int mid = (start + end) / 2;
            // 对左侧子序列进行递归排序
            mergeSort(a, start, mid);
            // 对右侧子序列进行递归排序
            mergeSort(a, mid + 1, end);
            // 合并
            merge(a, start, mid, end);
        }
    }

快速排序

原理:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

 

冒泡,选择,插入,希尔,归并,快速排序大合集,面试收藏必备

 

代码实现:

/**
     * 快速排序
     * @author 溪云阁
     * @param arr        待排序列
     * @param leftIndex  待排序列起始位置
     * @param rightIndex 待排序列结束位置
     */
    public static void quickSort(int[] arr, int leftIndex, int rightIndex) {
        if (leftIndex >= rightIndex) {
            return;
        } else {
            int left = leftIndex;
            int right = rightIndex;
            // 待排序的第一个元素作为基准值
            final int key = arr[left];
            // 从左右两边交替扫描,直到left = right
            while (left < right) {
                while (right > left && arr[right] >= key) {
                    // 从右往左扫描,找到第一个比基准值小的元素
                    right--;
                }
                // 找到这种元素将arr[right]放入arr[left]中
                arr[left] = arr[right];
                while (left < right && arr[left] <= key) {
                    // 从左往右扫描,找到第一个比基准值大的元素
                    left++;
                }
                // 找到这种元素将arr[left]放入arr[right]中
                arr[right] = arr[left];
            }
            // 基准值归位
            arr[left] = key;
            // 对基准值左边的元素进行递归排序
            quickSort(arr, leftIndex, left - 1);
            // 对基准值右边的元素进行递归排序。
            quickSort(arr, right + 1, rightIndex);
        }
    }

 

--END--

作者:@溪云阁

如需要源码,转发,关注后私信我。

部分图片来源网络,如侵权请联系删除,谢谢!



Tags:快速排序   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
人生有涯,学海无涯今天跟大家分享一个常用的排序算法&mdash;&mdash;快速排序。我想大家在日常的工作或者面试的时候肯定经常会遇到很多排序算法,而且快速排序算法往往是这里面...【详细内容】
2021-03-04  Tags: 快速排序  点击:(182)  评论:(0)  加入收藏
1、引言今天的运气不是很好,再加上项目的压力。准备停止学习一周,等把项目这一关过了,再继续深入学习分享算法。后来吧今天遇到的事情都比较郁闷,也无心情继续开发项目。便想转...【详细内容】
2020-11-12  Tags: 快速排序  点击:(234)  评论:(0)  加入收藏
算法05:Golang快速排序Quick Sort1.什么是快速排序(Quick Sort)快速排序是由东尼&middot;霍尔所发展的一种排序算法.在平均状况下,排序 n 个项目要 &Omicron;(nlogn) 次比...【详细内容】
2020-10-12  Tags: 快速排序  点击:(78)  评论:(0)  加入收藏
在很多大厂的面试中,算法是最基本的要求,像基础的算法,冒泡,选择,插入等,基本上都会问到。很多同学往往忽略了其重要程度,只注重编程语言,小编并不建议这样子,今天我们来梳理一下算法...【详细内容】
2020-05-03  Tags: 快速排序  点击:(46)  评论:(0)  加入收藏
看似青铜实则王者很多人提起快排和二分都觉得很容易的样子,但是让现场Code很多就翻车了,就算可以写出个递归版本的代码,但是对其中的复杂度分析、边界条件的考虑、非递归改造、...【详细内容】
2019-11-27  Tags: 快速排序  点击:(68)  评论:(0)  加入收藏
冒泡排序时间之所以效率低,就是因为将所有数都一视同仁不做区分挨个比较,这是最普通的做事方法,所以效率也是最普通的,时间复杂度为N的平方;而归并排序效率高,则是采用了分治的思...【详细内容】
2019-10-22  Tags: 快速排序  点击:(93)  评论:(0)  加入收藏
▌简易百科推荐
前言Kafka 中有很多延时操作,比如对于耗时的网络请求(比如 Produce 是等待 ISR 副本复制成功)会被封装成 DelayOperation 进行延迟处理操作,防止阻塞 Kafka请求处理线程。Kafka...【详细内容】
2021-12-27  Java技术那些事    Tags:时间轮   点击:(1)  评论:(0)  加入收藏
博雯 发自 凹非寺量子位 报道 | 公众号 QbitAI在炼丹过程中,为了减少训练所需资源,MLer有时会将大型复杂的大模型“蒸馏”为较小的模型,同时还要保证与压缩前相当的结果。这就...【详细内容】
2021-12-24  量子位    Tags:蒸馏法   点击:(11)  评论:(0)  加入收藏
分稀疏重建和稠密重建两类:稀疏重建:使用RGB相机SLAMOrb-slam,Orb-slam2,orb-slam3:工程地址在: http://webdiis.unizar.es/~raulmur/orbslam/ DSO(Direct Sparse Odometry)因为...【详细内容】
2021-12-23  老师明明可以靠颜值    Tags:算法   点击:(7)  评论:(0)  加入收藏
1. 基本概念希尔排序又叫递减增量排序算法,它是在直接插入排序算法的基础上进行改进而来的,综合来说它的效率肯定是要高于直接插入排序算法的;希尔排序是一种不稳定的排序算法...【详细内容】
2021-12-22  青石野草    Tags:希尔排序   点击:(6)  评论:(0)  加入收藏
ROP是一种技巧,我们对execve函数进行拼凑来进行system /bin/sh。栈迁移的特征是溢出0x10个字符,在本次getshell中,还碰到了如何利用printf函数来进行canary的泄露。ROP+栈迁移...【详细内容】
2021-12-15  星云博创    Tags:栈迁移   点击:(22)  评论:(0)  加入收藏
一、什么是冒泡排序1.1、文字描述冒泡排序是一种简单的排序算法。它重复地走访要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地...【详细内容】
2021-12-15    晓掌柜丶韶华  Tags:排序算法   点击:(16)  评论:(0)  加入收藏
在了解golang的map之前,我们需要了解哈希这个概念。哈希表,又称散列表(Hash table),是根据键(key)而直接访问在内存储存位置的数据结构。也就是说,它通过计算出一个键值的函数,将...【详细内容】
2021-12-07  一棵梧桐木    Tags:哈希表   点击:(14)  评论:(0)  加入收藏
前面文章在谈论分布式唯一ID生成的时候,有提到雪花算法,这一次,我们详细点讲解,只讲它。SnowFlake算法据国家大气研究中心的查尔斯&middot;奈特称,一般的雪花大约由10^19个水分子...【详细内容】
2021-11-17  小心程序猿QAQ    Tags:雪花算法   点击:(24)  评论:(0)  加入收藏
导读:在大数据时代,对复杂数据结构中的各数据项进行有效的排序和查找的能力非常重要,因为很多现代算法都需要用到它。在为数据恰当选择排序和查找策略时,需要根据数据的规模和类型进行判断。尽管不同策略最终得到的结果完...【详细内容】
2021-11-04  华章科技    Tags:排序算法   点击:(40)  评论:(0)  加入收藏
这是我在网上找的资源的一个总结,会先给出一个我看了觉得还行的关于算法的讲解,再配上实现的代码: Original author: Bill_Hoo Original Address: http://blog.sina.com.cn/s/bl...【详细内容】
2021-11-04  有AI野心的电工和码农    Tags: KMP算法   点击:(36)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条