homework.树.二叉树

概念

二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。

满二叉树

一颗二叉树中,如果所有的分支节点都存在左子树和右子树,并且所有的叶节点都在同一层上,这样的一棵二叉树称作满二叉树。

这里写图片描述

完全二叉树

定义:

  1. 完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。满二叉树必定是完全二叉树,完全二叉树不一定是满二叉树。
  2. 若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的节点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。

这里写图片描述

二叉树的性质

  1. 一颗非空二叉树第k层上最多有2k-1个节点。
  2. 一颗深度为k的二叉树中,最多拥有2k-1个节点。
  3. 一个非空的二叉树,如果叶节点数为n0,度数为2的节点数为n2,则n0 = n2 + 1。
  4. 具有n个节点的完全二叉树的深度为[log2n]+1。(高斯符号 [] = floor())
  5. 具有n个节点的完全二叉树,如果按照从上至下和从左至右的顺序对二叉树中的所有节点从1开始顺序编码,则对于任意的序号为i的节点:
    • 如果i>1,则序号为i的节点的双亲节点的序号为[i/2];如果i=1,的序号为i的节点为根节点,无双亲节点。
    • 如果2i 公式名n,则序号为i的节点的左孩子节点的序号为2i,如果2i>n,则序号为i的节点无左孩子。
    • 如果2i + 1公式名n,则序号为i的节点的右孩子节点的序号为2i+1;如果2i + 1>n,则序号为i的节点无右孩子。

二叉树的存储

顺序存储结构

用一组连续的存储单元存放二叉树中的节点。一般是按照二叉树的节点从上至下,从左至右的顺序储存。节点在存储位置上关系并不一定就是他们在逻辑上的关系。
这里写图片描述
如上图,树按照从上至下,从左至右存储到内存中。
索引0为根节点,索引为i的节点的子节点的索引为2i + 1和2i + 2,索引为i的父节点的索引为[(i - 1)/2]
例如索引为2的节点的子节点索引为2 * 2 + 1 = 5和2 * 2 + 2 = 6,父节点为[(2 - 1) / 2] = 0。
但是上图中用到的例子是一个完全二叉树,而非完全二叉树使用顺序存储结构的话,要想获取节点的子节点和父节点并且仍然满足上面的公式,就需要把非完全二叉树改造为完全二叉树再储存,否则就不会满足上面的公式,而改造一个非完全二叉树为完全二叉树,会造成大量的空间浪费。最坏的情况如下:一颗深度为k的右单支树,却需要分配2k - 1个存储单元。
这里写图片描述
所以,顺序存储结构仅适用于完全二叉树。

二叉链表存储结构

链表中每个节点由三个域组成,数据域和两个指针域(左子节点指针,右子节点指针)。
如果一个节点的子节点不存在,相应的指针域值为空。
节点的存储结构:
这里写图片描述
二叉链表示意图:
这里写图片描述

三叉链表存储结构

链表中每个节点由四个域组成,比二叉链表多了一个指向父节点的指针域。
节点的存储结构:
这里写图片描述
三叉链表示意图:
这里写图片描述

二叉树的遍历

将二叉树的根节点设为D,根节点的左子树设为L,根节点的右子树设为R。
那么遍历方式有:DLR,DRL,LDR,LRD,RLD,RDL。
限定先左后右,则仅有三种:DLR,LDR,LRD。
另外还有一种层次遍历,就是按照从上至下,从左至右,对节点进行逐个访问。

  • 先序遍历(DLR)
    1. 访问根节点;
    2. 先序遍历根节点的左子树;
    3. 先序遍历根节点的右子树;
  • 中序遍历(LDR)
    1. 中序遍历根节点的左子树;
    2. 访问根节点;
    3. 中序遍历根节点的右子树;
  • 后序遍历(LRD)
    1. 后序遍历根节点的左子树;
    2. 后序遍历根节点的右子树;
    3. 访问根节点;
  • 层次遍历

深度优先遍历:先序遍历,中序遍历,后序遍历。
广度优先遍历:层次遍历。

example1:
这里写图片描述
example2:
这里写图片描述
example3:
这里写图片描述

  • 先序遍历:
    • example1:1,2,4,8,9,5,10,11,3,6,12,13,7,14,15
    • example2:f,b,a,d,c,e,g,i,h
    • example3:a,b,d,e,g,h,i,c,f
  • 中序遍历:
    • example1:8,4,9,2,10,5,11,1,12,6,13,3,14,7,15
    • example2:a,b,c,d,e,f,g,h,i
    • example3:d,g,h,i,e,b,f,c,a
  • 后序遍历
    • example1:8,9,4,10,11,5,2,12,13,6,14,15,7,3,1
    • example2:a,c,e,d,b,h,i,g,f
    • example3:i,h,g,e,d,f,c,b,a
  • 层次遍历
    • example1:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
    • example2:f,b,g,a,d,i,c,e,h
    • example3:a,b,d,c,e,f,g,h,i

层次遍历算法:

  1. 建立一个队列;
  2. 将根节点指针入队列;
  3. 从队列取出一个元素;
  4. 访问该元素所指的节点,若该元素所指节点的左,右子节点非空,则将该元素所指节点的左子节点指针和右子节点指针顺序入队列;
  5. 重复3步骤;

以上面的example1为例:

  • 将指向1的指针入队列;
  • 取出指向1的指针,获取1节点,获取1节点左子节点指针和右子节点指针;
  • 将指向2节点和指向3节点的指针顺序入队列;
  • 取出指向2节点的指针,获取2节点,获取2节点左子节点指针和右子节点指针;
  • 将指向4节点和指向5节点的指针顺序入队列;
  • 取出指向3点节点的指针,获取3节点,获取3节点左子节点指针和右子节点指针;
  • 将指向6节点和指向7节点的指针顺序入队列;
  • ……
    当队列取完,二叉树遍历完毕。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值