当前位置:   article > 正文

万字梳理:算法0基础入门-主流排序算法大集合;硬核整理图解+代码--数据结构与算法小结4_阿伟算法笔记,万字整理

阿伟算法笔记,万字整理

本期脑图:

图片

图片

1.前言:谈算法色变?Duck不必!

    不知你是否有这种感受?一提到算法,第一反应就是:太难了,我不会!一开始我也有过这种感受,不过耐心学下去之后发现,算法并没有那么复杂。至少入门是一件很容易的事情,只需要:

    1.耐心看完本篇推文!

    2.开始思考任意一个算法实现思路!

    3.自己尝试写任意一个实现代码!

只要成功写出一个,你就入门了,你一定可以做到!至于后期深入到什么程度,就取决于你付出的时间多久了~

2.一定要掌握算法吗?

    个人认为:这取决于对自己的要求,如果对自我的要求是做一个普通的开发人员,不学算法问题不大。日常应付CRUD简单需求就可以了(一般月薪2W就是天花板了)。

    但是如果想成为一个高级开发工程师或者想入大厂,年薪50W以上,算法是必过的一个门槛,大厂的面试中光是算法板块就可以卡掉很多人~所以算法重要与否,主要取决于对自己的要求!

            下图为一位面试过某跳动大厂遇到的两个算法题的其中一个:

图片

图片

3.开始入门:排序算法

    算法有很多,本篇入门主讲排序算法;生活当中有很多场景需要用到排序,比如经常逛淘宝,有人就需要按照价格从低到高来排序;再比如我们经常看到的微博热搜排名,其实也是一种根据用户点击量进行的排序,可以说生活无处不排序,那么多排序,底层到底怎么做的呢?排序算法走起~

    排序算法按照不同标准可以分为不同类,不过就入门而言知道这些分类名称帮助不大,所以省掉那些复杂的,直接按照难易程度分成两类:

    一 简单排序:1.冒泡排序    2.选择排序    3.插入排序(适合入门)

    二 复杂排序:1.希尔排序    2.归并排序    3.快速排序(适合进阶)

    3.1    冒泡排序

        建议:算法学习三步走:(偶尔四步)

图片

    第一步:什么是冒泡排序?

        冒泡排序(Bubble Sort):重复地访问要排序的元素列,依次比较两个相邻的元素,如果顺序符合要求(如从大到小)就把他们交换过来。此过程重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。

这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同水中气泡最终会上浮到顶端一样,故名“冒泡排序”。上例子:

一个数组长这样:

Integer[] arr = {85, 7, 9, 56, 47, 1, 2, 8, 5};

假如竖着看,就变成这样:

图片

所以现在要做的就是将数组中的 数值大的元素“浮”到上面,就像吐泡泡,上面的泡泡更大(数值更大);(配图仅仅为了更便于理解)

    第二步:冒泡排序算法图解

    需求,一串数组:3 5 9 7 2 1,要求排序后结果从小到大:1 2 3 5 7 9。

先看一下冒泡排序整体过程,有个整体印象:

图片

    第一轮冒泡分解步骤(每一轮过程相似):

1.元素3和相邻元素5比较,3<5,不交换位置;

图片

2.元素5和元素9比较大小:5<9,不交换位置;

图片

3.元素9和元素7比较大小:9>7,交换位置;

图片

4.换到新位置的元素9和元素2比较大小:9>2,交换位置;

图片

5.换到新位置的元素9和元素1比较大小:9>1,交换位置,右边没有元素,第一轮结束;

图片

6.第一轮冒泡结束后数组现状:最大元素找到相应位置;

图片

第二轮冒泡排序:将第二大的元素放在对应位置;

第三轮冒泡排序:将第三大的元素放在对应位置;

第四轮冒泡排序:将第四大的元素放在对应位置;

第五轮冒泡排序:将第五大的元素放在对应位置;

也就是说有N个元素,就会有N-1轮排序;每一轮交换过程类似,在此不做赘述;

    第三步 手写代码实现冒泡排序

    需要实现的API:(建议先自己先code一下,过程比结果更重要

1.sort(Comparable[] a):遍历, 调用greater和exchange方法完成排序;

2.greater(Comparable c1, Comparable c2):比较两个相邻元素的大小;

3.exchange(Comparable[] a, int b, int c) :交换两个元素的位置;

后续排序算法实现均需要greater();exchange();后续将不再列出;

public class MyBubble {
      //排序    public static void sort(Comparable[] a) {
          //length-1个元素需要进行交换的过程        for (int i = 0; i < a.length - 1; i++) {
              //要从索引0处的元素开始交换,最坏情况一直交换到length-1次;            for (int j = 0; j < a.length - 1 - i; j++) {
                  //比较假如a[j]a[j+1]大,则交换位置                if (greater(a[j], a[j + 1])) {
                      exchange(a, j, j + 1);                }            }        }    }    //比较大小    public static boolean greater(Comparable c1, Comparable c2) {
      /*    //return c1.compareTo(c2) > 0; 的拆解版:    int compare = c1.compareTo(c2);    return compare > 0;*/        return c1.compareTo(c2) > 0;    }    //交换位置    public static void exchange(Comparable[] a, int b, int c) {
          //建立一个临时元素,用于交换中转        //第一个函数等号后面的元素就是下一个函数的等号前面的元素,首尾衔接,即完成交换        Comparable num = a[b];        a[b] = a[c];        a[c] = num;    }}

        补充:精力充沛的可以思考一下冒泡排序的时间复杂度是多少?

提示,假设冒泡排序的最坏情况:一个含有N个元素的完全倒序的数组需要交换多少次完成排序?

        推导过程(过程比结果更重要!)

    第一个元素需要交换的次数:N-1

    第二个元素需要交换的次数:N-2

    第三个元素需要交换的次数:N-3

    ......

    第N-1个元素需要交换的次数:1

    第N个元素不需要交换,此时已经正序了;

    最后一共需要交换次数:1+2+3+...+N-1 = (N*(N-1))/2=N^2/2 - N/2;

    按照时间复杂度的去杂规则,最后时间复杂度简化为:

    F(N)= O(N^2);

图片

    3.2    选择排序

    第一步    什么是选择排序?

    选择排序(Selection sort)的工作原理是:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/390485
推荐阅读
相关标签
  

闽ICP备14008679号