https://www.gravatar.com/avatar/7a0c24f697ea1587001c36d00039b60f?s=240&d=mp

十大经典排序算法动画与解析,看我就够了!(配代码完全版)

本文转载自程序员小吴公众号[https://mp.weixin.qq.com/s/vn3KiV-ez79FmbZ36SX9lg]

排序算法是《数据结构与算法》中最基本的算法之一。

排序算法可以分为内部排序外部排序

内部排序是数据记录在内存中进行排序。

而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。

常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。

用一张图概括: http://img.ibook8.club/15716553814734.jpg

关于时间复杂度:

  1. 平方阶 (O(n2)) 排序 各类简单排序:直接插入、直接选择和冒泡排序。
  2. 线性对数阶 (O(nlog2n)) 排序 快速排序、堆排序和归并排序;
  3. O(n1+§)) 排序,§ 是介于 0 和 1 之间的常数。 希尔排序
  4. 线性阶 (O(n)) 排序 基数排序,此外还有桶、箱排序。

关于稳定性:

  1. 稳定的排序算法:冒泡排序、插入排序、归并排序和基数排序。
  2. 不是稳定的排序算法:选择排序、快速排序、希尔排序、堆排序。

1. 冒泡排序

1.1 算法步骤

  • 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
  • 针对所有的元素重复以上的步骤,除了最后一个。
  • 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

1.2 动画演示

http://img.ibook8.club/冒泡排序动画演示.gif

1.3 参考代码

 // Java 代码实现
 public class BubbleSort implements IArraySort {
 
     @Override
     public int[] sort(int[] sourceArray) throws Exception {
         // 对 arr 进行拷贝,不改变参数内容
         int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
 
         for (int i = 1; i < arr.length; i++) {
            // 设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已经完成。
            boolean flag = true;

            for (int j = 0; j < arr.length - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    int tmp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = tmp;

                    flag = false;
                }
            }

            if (flag) {
                break;
            }
        }
        return arr;
    }
}

2. 选择排序

2.1 算法步骤

  • 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
  • 再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
  • 重复第二步,直到所有元素均排序完毕。

2.2 动画演示

http://img.ibook8.club/选择排序动画演示.gif

在阿里,我如何做好技术项目管理?

以下文章来源于阿里技术 ,作者墨玖(来自:阿里技术公众号)

http://img.ibook8.club/15716538675015.jpg

阿里妹导读:在技术公司、尤其是互联网公司,技术人员作为PM(项目经理)是非常常见的。有些同学得心应手,有条不紊,能得到清晰稳定的预期结果;有些同学则在过程中遇到各种闹心的事,最后不是项目上不了线,就是带着问题或各种人员的不满硬上。当然这两种都是比较极端的结果。理性思考下,这里面有没有规律在?今天,阿里高级开发专家墨玖和你聊聊,如何做好一个技术项目的 PM。

目标分析

对于任何事情要有清晰的目标才能精确把握,如何做好一个技术项目的PM?首先我们看到这里面目标最起码应该是:如期交付有质量保障的项目产出。这里有几个需要我们注意的结果关键词:如期交付(守时守信)、质量保障(保质保量)、项目产出(完整结果)。当然还有最重要的因素:人 + 过程。阿里有句老话叫做:没有结果的过程是放屁,没有过程的结果是垃圾。所以,项目管理也是一样。我们既要结果,又要过程,当然,还要这里面人舒服

这里我们再总结提取下目标:

  1. 项目目标:如期交付(守时守信)、质量保障(保质保量)、项目产出(完整结果);
  2. 人员目标:舒服、有成就、有成长;
  3. 过程目标:风险控制、信息同步。

接下来我们就按照项目的生命周期来看看以上目标要怎样才能更好地达成。

目标达成

★ 项目启动

项目启动重要点是需求宣讲,俗称画饼拉人 。任何一个项目都会有既定的目标和预期,但是这个目标大家认不认?如何衡量结果好坏?做完后有没有成就感?这是项目后续成败的关键。所以你需要思考好这些东西,才能和大家宣讲、才能拉人干事。不然人家都不知道你要干啥、干了有啥好、为啥要(卖力)给你干。作为项目PM的你定义好项目目标、衡量结果(ROI)、人是尤为重要的 。这里提几点建议和思考。

  1. 目标:你为何要做这件事?
  2. 目标:你的目标有没有足够明确?有没有清晰的大图?
  3. 目标:做这件事的意义是什么?
  4. 结果:你有没想清楚个目标的关键因素,核心指标是什么?
  5. 结果:有没有附加的影响和因素?是好的还是坏的?
  6. 人:你自己是否足够清晰能够完成项目的重要因素?尤其是大的项目top-down的思考。
  7. 人:你能为大家提供什么来确保顺利的分工配合?越俎代庖阻、撒手不管都是不可取的。
  8. 人:这个项目需要哪些人?哪些角色?他们核心关键是哪些?
  9. 人:参与这个项目的同学能得到什么?失去什么?共赢吗?
  10. 人:参与的同学的成就感在哪里?

当你思考和整理好以上这些东西,才能做好项目(需求)的启动和宣讲。目前我们很多项目的组织方式,是由多个角色完成的。常见的方式是运营或业务或产品做了项目中的一部分或所有,然后到需求阶段再由技术同学跟进后半段。这个角色有多人共同分担并不冲突,重要的是我们要配合默契、衔接得当、相互补位,拿到共赢结果。

工作过程中我见到过激情澎湃的KO,也见过稀里糊涂到直接开车,所以生活(工作)还是需要一些仪式感。注意做好这些点,项目后面会顺畅很多。

http://img.ibook8.club/15716538544395.jpg

★ 需求评审

一般需(hua)求(bing)宣(la)讲(ren)完毕后,很快会进入需求评审阶段。这里是需求细化明确重要节点。作为一个项目PM你必须要做到小需求了如指掌、大需求合理拆分。这个阶段最好是个时间段而不是一个时间点。尤其是对于互联网,我们讲究的是快速,节约大家时间。你有必要提前深入介入,了解需求逻辑和范围。这里会遇到如下几类问题:

1.需求(描述或意义)不明确、理解不一致。 解:不要牵强、不要害羞。描述不清楚的讲(写)清楚;意义不清楚的增加解释。PM都要搞清楚搞明白,这样你才能够在中后期答疑解惑环节,节约信息同步成本。实在不行就回到最开始的目标上去:意义在哪里?

2.关键人员没拉到到位。解:这个其实我们经常会遇到,原因也有很多。事前列好人员信息版(可以放心里)是一个很好的习惯,我个人习惯用钉钉群公告+云雀 note 页。事中则需要补救和充分沟通了,还好我们的同学都很能相互理解。

3.需求范围膨胀。解:这个问题也是我们项目中常见导致项目最终崩溃的原因。所以你是需要提早接入需求的,最起码要比评审早。确认好项目的人员投入数量、投入度,确认好本次重要目标和次要目标。适当的时候要做需求拆解,不要做超量(加班也可能搞不定)的计划。不要做好好先生。你要清楚你的职责是如期交付有质量保障的完整结果。

除以上问题外,对于大型的跨团队的项目可能当下是无法详细看清全局的。这就需要大PM在这个时候量力而行尽早分拣分派、划定二级责任人。在互联网公司,需求评审过不过一般都会提到需求沟通和宣讲。所以,需求评审一般是PM认同了项目目标和意义的,这个要特别注意。所以具有PM角色的你(们)要更多的做配合需求拆分细化、答疑解惑;而不是一堆问题瞎怼(这可以发生在宣讲或再靠前)。这里我提下几个重要的点。

  1. 需求评审要提前做好信息充分公开有会议邀请,关键人员要拉到位。
  2. 评审后关键参与人明确自身工作目标和职责。
  3. 重要信息、问题和困难收集。同时做好信息公开同步。
  4. 重大设计、困难单列单独跟进。

完成以上后,项目人员也基本铺开了。接下来更多的需要并行。

Mac和iPhone的接力功能失效怎么办?

某天用iPhone上网冲浪时,突然发现Mac上没有自动弹出Safari的网页提示。瞎折腾了一阵子(连蓝牙,重置网络设置等等)发现并不可行。重新安装系统,恢复手机设置是不可能的。最终折腾后发现一个有用的方案。

iPhone-设置-退出Apple ID并重新登录,然后发现接力功能恢复。

JavaScript中普通接口和默认接口的区别

ES6的模块化功能主要有两个关键字: exportimport

export主要用于模块对外暴露接口。 import用于引入其他模块暴露的接口。

export

export有两种用法:

export default foo
export foo

exportexport default均可用于导出常量、函数、文件、模块等 一种是直接导出,一种是导出默认。区别在于export default导出的是一个默认的变量

这两种的区别在于:

  1. export default 在一个模块里只能有一个,但是export可以有多个
  2. 通过export方式导出,在导入时要加**{ }**,export default则不需要
  3. export能直接导出变量表达式,export default不行 例如: export var foo='...' 是合法语句,但是export default var foo='...'是不合法的
  4. 模块中通过export方式导出的可以重新赋值,但是通过export default导出的无法修改 例如:
let e1='e1e1e1';
let e2='e2e2e2';
export {e1};
export default e2;
e1='hahahaha';
e2='hahahaha';

//执行结果
console.log(e1);
console.log(e2);

hahahaha
e2d2e2

import

export (default)导出的模块,在其他模块中可以通过import导入

不同的是:

使用export foo导出的,导入时需要加个大括号

import {foo} from './a'

通过as重命名

import {foo as e1} from './a'

使用export default foo导出的,导入时不用加入大括号

import foo from './a'