树
树是这样的一种结构: 对于树的定义如下:树是 n (n >= 0) 个结点的有限集,n = 0 时称为空树,在任意一棵非空树中,对于树的存储方式, 可以使用三种表示法来存储树之间结点之间的相互关系:双亲表示法, 孩子表示法, 孩子兄弟表示法双亲表示法:以一段连续的空间存储树的结点, 在每一个结点中,存储当前结点其双亲结点的存储位置: data为数据域, 存储当前结点的相关数据, parent 为指针域, 存储当前节点的双亲结点在数组中的下标比如下面的树使用双亲表示法表示: 根结点的双亲位置为 -1;上面的表示法表示的树用于查找结点的双亲元素比较方便, 但是,如果这个结点下面包含有多个的子结点, 我们可以需要设置多个的指针域, 比如, 长子域, 右兄弟域等等。孩子表示法:孩子表示法的方式是:将每个结点的孩子结点排列起来,以单链表作为存储结构,则 n 个结点有 n 个孩子链表,如果是叶子结点, 那么这个单链表为空,然后 n 个头指针又组成一个线性表,存放在一个一维数组中。使用孩子表示法表示上面的树形结构: 在上面的孩子表示法中,设计有两种结构:
- 有且仅用一个特定的称为 根(root)的节点
- 当 n > 1 时,其余结点可分为 m(m > 0)个互不相交的有限集 T1, T2, ...Tn, 其中每一个集合本身也是一棵树, 并且称为 根的子树,
- 孩子链表 child 为数据域, 用来存储当前的子结点在表头数组中的下标, next 为指针域,存放的是下一个孩子的这个结构指针地址。
- 表头结点 表头结点存储每个结点, 用于树形结点的遍历使用,另外, 存储长子结点的指针域;
二叉树
二叉树的定义
二叉树是 n 个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两棵互不相交的,分别称为 根结点的左子树和右子树的二叉树组成二叉树的特点:
- 每个结点最多有两棵子树
- 左子树和右子树是有顺序的, 并且不能颠倒
- 即使树中某结点只有一棵子树,也要区分顺序
二叉树的存储
顺序存储
按照顺序存储二叉树, 主要是使用一维数组来顺序存储树中的各个结点,比如, 存储如下树结构: 使用顺序存储如下: 对于不存在的结点, 我们将不存在的结点设为^
即可。使用顺序存储存在的问题在于, 我们需要对于不存在的结点分配存储空间,比如,对于下面这个右斜树而言:
这样造成了存储空间的浪费。链式存储
对于二叉树结点的存储, 我们使用一种被称为 “二叉链表” 的链式存储结构来存储,二叉链表是下面的这种结构: 这个结构中包含有一个数据域和两个指针域, 数据域表明当前结点的数据,指针域分别为二叉树左右两个结点的地址指针。使用链式存储后的最终的存储链表结构如下:二叉树的遍历
二叉树的遍历是指从根结点出发, 依次访问到二叉树中的每一个结点,使得每个结点被访问到并且仅被访问到一次。二叉树的遍历方法, 按照访问次序的不同, 可以分为 前序遍历, 中序遍历 以及 后序遍历前序遍历
前序遍历的遍历顺序是先访问二叉树的左子树, 然后访问二叉树的右子树 如, 上图, 二叉树的访问顺序是:ABDGHCEIF中序遍历
中序遍历根结点的左子树,然后是访问根结点,最后中序遍历右子树 如上图, 那么 二叉树的访问顺序是:GDHBAEICF后序遍历
判断二叉树是否为空, 如果是空, 那么空操作返回,否则的话, 从左到 右通过先叶子后结点的方式遍历访问左右子树 使用后序遍历的方法来访问二叉树的顺序是:GHDBIEFCA二叉树的创建
二叉树的创建可以像二叉树创建方法中传入一串树来实现,通过一定的二叉树的遍历顺序来依次创建结点, 对于空结点, 二叉树中的字符串可以为 ‘#’按照前序遍历创建的二叉树的方法如下:1 | // 创建二叉树 |
undefined
, 或者 0
等导致属性访问后为 false
的值。可以使用 hasOwnProperty
的方式来判断属性是否在对象上面:1 | Object.hasOwnPropery(prop); |
hasOwnProperty
属性覆盖掉从对象上面继承的, 我们需要通过 Object
来调用:1 | Object.hasOwnProperty.call(obj, 'property'); |