++i和i++的区别

简述

二者的区别本质上在于++i属于左值操作,而i++属于右值操作,可分以下几种情况分析:

Read more

跳表(skiplist)

简述

跳表是一种基于并联的链表,底层是一个普通的有序链表,更高层链表是基于随机方式构建的稀疏子链表,充当下层链表的快速通道,因此链表的长度由低到高层层递减。

跳表的查找、插入和删除操作的平均时间复杂度都为O(logn),有效地解决有序链表查询效率低下的问题。

注意:跳表的最底层必须是一个有序链表。

Read more

红黑树(Red-black tree)

简述

红黑树同AVL树一样也是一种自平衡二叉搜索树,不同于AVL树是高度平衡树,红黑树属于近似平衡树。

所谓近似平衡就是对平衡的要求相对宽松,不像AVL树那么严格。红黑数的平衡标准是:任一节点的左右子树的高度差小于两倍。

Read more

二叉搜索树(BST)

简述

二叉查找树(Binary Search Tree),又叫有序二叉树,具有以下3个性质:

  • 左子树如果不为空,那么它所有的节点的值都小于它的根节点
  • 右子树如果不为空,那么它所有的节点的值都大于它的根节点
  • 任意节点的左、右子树都是二叉查找树。
Read more

初识汇编-知识点摘记

汇编语言的由来

  • 汇编语言是基于机器语言(由0或1组成)而产生的一种助记符
  • 汇编语言介于机器语言和高级语言之间
  • 汇编语言与机器语言是一一对应关系,每条机器指令都有对应的汇编指令
  • 汇编语言通过编译得到机器语言,反之机器语言也可通过反汇编得到汇编语言
  • 高级语言通过编译得到汇编语言,但是汇编语言不能反汇编成高级语言,因为高级语言与汇编之间是多对一的关系。
Read more

《Effective Modern C++》条款24:区分万能引用和右值引用

简述

万能引用和右值引用都用”T&&“表示。

  • 万能引用

    所谓万能引用,即它既可以绑定左值,又可以绑定右值。一般用于表示型别推导的结果。

  • 右值引用

    右值引用,顾名思义就是只能绑定到右值,它的主要作用是作为可移动对象的标识。

Read more

《Effective Modern C++》条款23:理解std::move和std::forward

简述

  • std::move

    std::move,即移动语义。它的设计初衷在于让编译器用一种低成本的移动操作替换昂贵的复制操作。与之相关的两个函数分别是移动构造函数和移动赋值运算符。

    此外,std::move使得创建一个只可移动不可复制的对象成为可能,比如std::unique_ptr、std::future和std::thread等。

  • std::forward

    std::forward,即完美转发。它的设计初衷是使对任何一个函数模板,都可以将当前函数所接受的实参原封不动地转发给其它函数,且目标函数接受到的实参与传入当前函数的实参完全相同,包括实参的左右值属性。

  • 形参总是左值

    所谓左值,简单地说就是可寻址变量,而右值则是不可寻址的临时变量。

    1
    2
    3
    int a = 3;  // a是左值,3是右值
    a = a + 1; // 等号左边的a是右值,等号右边的a是右值
    // CPU取a的值存入临时变量,即寄存器,然后+1,再将寄存器的值赋值给a

    实参既可以是左值,也可以是右值。而形参总是左值,原因在于形参是为了传递实参的值或指针或引用而出现的,因此必须是可被赋值的左值。即便形参的类别是右值引用,如下:

    1
    void fun(Widget&& w);  // 形参w是一个左值
Read more