Python数据结构:树形结构

由一个根节点和子节点组成的结构。子节点个数可以为0。
若每个根节点z最多有可以有 n n n个子节点,那么它就叫做 n n n叉树。

二叉树

为什么使用二叉树

一般树形结构在计算机中的存储方式是以链表为主。

假设一个 n n n叉树,共有 m m m个节点(根节点加上子节点)。
那么它们一共会有 m n mn mn个链接。
但是实际上只会用到 m − 1 m-1 m1个链接。

空置的链接数为 m ( n − 1 ) + 1 m(n-1)+1 m(n1)+1
空置率为 ( m ( n − 1 ) + 1 ) / m n (m(n-1)+1)/mn (m(n1)+1)/mn

所以当 n n n越大,链接空置率越高。

2叉树的链接空置率大概为 1 / 2 1/2 1/2
3叉树的链接空置率大概为 2 / 3 2/3 2/3
4叉树的链接空置率大概为 3 / 4 3/4 3/4

所以使用2叉树能够最大限度的利用链接。

二叉树最多只有两个节点:左节点和右节点。

满二叉树
高度为 h h h,节点数为 2 h − 1 2^h-1 2h1的树。
也就是说二叉树的每一层都放满了。

完全二叉树
每一层都从上往下,从左往右的存放节点。

斜二叉树
完全没有左子树或者右子树。

严格二叉树
每一个父节点都有两个子节点。

二叉树的存储方式:

一维数组
父节索引为i,左子节点索引为 ( 2 i + 1 ) (2i+1) (2i+1),右子节点索引为 ( 2 i + 2 ) (2i+2) (2i+2)
链表
每个节点都是一个类的实例,实例有3个属性,分别是value(值),left(左节点指针),right(右节点指针)

二叉查找树

二叉查找树具有以下特点:

  1. 可以是空集。
  2. 每一个树根的值要大于左节点的值 。
  3. 每一个树根的值要小于右节点的值 。
  4. 左右子树也是二叉查找树 。
  5. 树的每个节点的值都不同。

二叉树的遍历

前序遍历、中序遍历、后序遍历、层次遍历。
前中后序遍历实际上指的是树根节点访问的顺序,树根在前为前序,树根在中为中序,树根在后为后序。

使用递归函数能很快的实现这三种遍历。
前序遍历
访问顺序为:中左右
访问树根>访问左子树>访问右子树

def preorder(ptr):
    if ptr!=None:
        print(ptr.value)
        preorder(ptr.left)
        preorder(ptr.right)

中序遍历
访问顺序为:左中右
访问访问左子树>树根>访问右子树

def inorder(ptr):
    if ptr!=None:
        preorder(ptr.left)
        print(ptr.value)
        preorder(ptr.right)

后序遍历
访问顺序为:左右中
访问访问左子树>访问右子树>树根

def inorder(ptr):
    if ptr!=None:
        preorder(ptr.left)
        preorder(ptr.right)
        print(ptr.value)

层次遍历
从上往下,从左往右的遍历二叉树。
可以用广度优先遍历来实现。
先遍历根节点,然后将左右子节点压入队列,再弹出队列的第一个元素,压入该节点的左右子节点,重复以上过程。

二叉树的删除

分三种情况:

  1. 删除的节点为叶节点:直接将其父节点指向None
  2. 删除的节点只有一颗子树,直接将该节点的父节点和该节点的子节点相连。
  3. 删除的节点有2颗子树:有两种处理方法:
    a. 将该节点用该节点的左子树中的最大值取代(一直往右找,直到为None)
    b. 将该节点用该节点的右子树中的最小值取代(一直往左找,直到为None)

二叉运算数

感觉用不上,略。

线索二叉树

将二叉树中闲置的节点利用起来,左指针指向上一个节点,右指针指向下一个节点,这样在遍历的时候,就不用使用递归就可以直接遍历二叉树。
同样感觉用的不多,略。

多叉树和森林转换成二叉树

树转化成二叉树:CHILD-SIBLING法则。

确定唯一二叉树

若知道中序和前序 或者 中序和后序的遍历结果,就能确定唯一的二叉树。

优化查找二叉树

在所有可能的二叉树中,成本最小的二叉树。

扩充二叉树

n n n个节点的二叉树中有 n − 1 n-1 n1个链接是使用的,有 n + 1 n+1 n+1个链接是闲置的。
在这 n + 1 n+1 n+1个闲置的位置上添加一个节点,这些节点叫做“外节点”。其它的节点叫做“内节点”。
内径长:所有内节点到树根距离的总和
外径长:所有外节点到树根距离的总和
加权外径长:若每个外节点都有一个权重,那么权重乘距离的和叫加权外径长。

霍夫曼树

叶节点上存放着信息。对应每个叶节点都有一个权值。霍夫曼树外径长最小。
这样大权重的数据会被优先访问到。

平衡二叉树

AVL树。
每次插入数据或者删除数据后,必要时会对二叉树做一些高度的调整。
平衡树的定义:二叉树的左右子树都是平衡树,二叉树左右子树高度差不超过1。
将非平衡树调整为平衡树
找到非平衡树中的不平衡点,将它边为平衡。
不平衡点主要分 L L , R R , L R , R L LL,RR,LR,RL LL,RR,LR,RL四种类型。
我们只需要将对应的类型调整为平衡二叉树即可。

B树

二叉查找树的扩展。

每个二叉查找树的节点都有一个值,且满足父节点的值大于左子节点,小于右子节点。

若有这样一种树:每个节点可以存有a,b个值,且每个每个节点存在3个链接,左链接的值都小于a,右链接的值都大于b,中链接的值在a,b之间。
同理,若每个节点可以存放 n − 1 n-1 n1个值,存在 n n n个链接,数据存放规则同上,那么这样的树就叫做B树

参考书籍:《图解数据结构–使用Python》
部分代码请点击

你可能感兴趣的:(数据结构)