树是一种数据结构,单位为Node(节点)。不同于链表的直线排列,树呈现一种自上而下的分层排序规则。 树->数据结构: 单元为Node(节点)->当这样的节点多了 就可以关联出不同的形态 一个父节点有一个左子节点,有一个右子节点 有的节点下方没有其他数据 也就没有左子节点和右子节点了 事实上,每一个节点都是一个独立的对象。存在着: a.本身储存的值 b.父节点地址 c.左子节点地址 d.右子节点地址 看到这里,我们会想到链表。因此链表也是有数据域和指针域 你会发现 如果我们聚焦目光于一个节点 同链表相比,二叉树的节点在数据域上是相差无几的 只是指针域被分成了三个部分:父节点的地址,左子节点的地址,右子节点的地址 树结构中,普及一些专业名词: 1.度:每一个节点的子节点数称为度。普通二叉树的非根节点和最底层节点的度均是2 2.二叉树:我们同样观察到,有一种树最上层的节点没有父节点 最下层的节点没有左右子节点,我们将一种度<=2的的数据结构称为二叉树 3.树的高度:也就是树的总层数。 4.根节点:最上层的节点(只有唯一一个) 5.根节点的左子树:这个左子树相当于以其左子节点作为一棵新树的根节点 由这个左子节点衍生出来的一整棵树都是根节点的左子树 6.根节点的右子树:原理如上。 7.二叉查找树: 二叉查找树是一种特殊的二叉树,它具有以下性质: 1.每一个节点上最多有两个子节点(首先是一个二叉树) 2.任意节点左子树的大小均小于当前节点 3.任意节点的右子树的大小均大于当前节点 添加原则: 1.小的存左边 2.大的存右边 3.一样大的不存 8.二叉树的遍历方式 a.前序遍历:从根节点开始,按照 当前->左子树->右子树顺序遍历 b.中序遍历(最重要):按照左子树->当前节点->右子树顺序遍历 c.后序遍历:按照左子树->当前->右子树的顺序进行遍历 d.层序遍历:从上到下一个一个取 注意 先左后右 这个东西很好理解 前序就是当前节点最先获取 中序就是当前节点在中间获取 后序就是当前节点在最后获取 —————————————————————————————————————————————————————————————————————— 二叉查找树的弊端: 7 10 11 12 13 按照二叉查找数 首先存7作为根节点 然后10放11后面 大概的样子就是 7 10 11 12 13 现在这一棵二叉树似乎变成了一个单向链表 但是此时两边的树是不一样长的 这样的树是有问题的 这样的查询效率过低了 如果我要查询数据13 岂不是要从根节点开始 找5次才能找到13 关键点:要提高查询效率 左右的高度要差不多长的树-> 这里我们就引入了一个新的二叉树 这样的二叉树是基于二叉查找树的 增加一条新的规则:任意节点左右子树的(高度差)不超过1 (这点很容易迷惑 任意的意思是从上往下的每一个节点) 不能被根节点的左子树右子树的高度满足条件迷惑 当你看根节点左右子节点的时候 就会发现可能子节点不满足这个条件 ———————————————————————————————————————————————————————————————————————— 平衡二叉树的旋转机制: 规则1:左旋(前提条件:添加了一个节点后,该树不是一颗平衡二叉树) 规则2:右旋(当添加一个节点之后,该节点不是一棵平衡二叉树) 研究左旋转规则: 1.确定支点:从添加的节点开始,不断地朝父节点寻找不平衡点 2.将根节点的右边往左边拉 3.原先的右节点变成新的父节点,并且把多余的左子节点出让 给已经降级的根节点当右节点 研究右旋规则: 1.发现添加节点后,平衡被破坏了,从被添加的节点开始向上找第一个不平衡的点 2.找到第一个不平衡的点作为支点 3.原先的左子节点变成新的父节点,并且把多余的右子节点出让 给已经降级的根节点当左节点 —————————————————————————————————————————————————————————————————————————————— 平衡二叉树需要旋转的四种情况 1.左左:根节点的左子树的左子树不平衡,导致二叉树不平衡->一次右旋就可以 2.左右:根节点的左子树的右子树不平衡,导致二叉树不平衡->一次局部左旋和整体一次右旋 ps:这里很有意思 就是要先把左右问题变成左左问题 再转化为左左的问题 3.右右:就是根节点的右子树的右子树不平衡,导致二叉树不平衡->一次左旋就可以 4.右左:根节点的右子树的左子树不平衡,导致二叉树不平衡->一次局部右旋和整体一次左