树和二叉树学习笔记(21.10.26)

Posted 未定_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树和二叉树学习笔记(21.10.26)相关的知识,希望对你有一定的参考价值。


一、树的逻辑结构

1.定义

  • 树: n(n>=0)个结点的有限集合,树中的数据元素称为结点。n=0时为空树。
  • 非空树的条件:
    ·有且仅有一个特定的称为根的结点;
    ·当n>1时,除根结点外其余结点被分成m(m>0)个互不相交的有限集合,每个集合又是一棵树,并称为这个根结点的子树。
  • (注意: 结点不能属于多个子树,子树之间不能有关系,否则就不是树)

2.基本术语

  • 度:
    结点的度:结点所拥有的子树的个数。
    树的度:树中各结点度的最大值。
  • 结点:
    叶子结点:度为0的结点,也叫终端结点。
    分支节点:度不为0的结点,也叫非终端结点。
    ·孩子结点:某结点子树的根结点为这个结点的孩子结点。
    ·双亲结点:某结点子树的根结点为这个结点的孩子结点,这个结点为它孩子结点的双亲结点。
    ·兄弟结点:具有同一双亲的孩子结点互称为兄弟结点。
  • 路径: 如果树的结点序列n1,n2…nk有如下关系:结点ni是ni+1的双亲,把n1,n2…nk称为一条由n1至nk的路径,路径上经过的边的个数称为路径长度
  • 祖先: 树中有一条路径能从结点x到结点y,那么x就称为y的祖先,y称为x的子孙
  • 结点所在层数: 根结点层数为1,其余任何结点,若某结点在第k层,则其孩子结点在第k+1层。
  • 树的深度: 树中所有结点的最大层数为树的深度,也称高度。
    树的宽度: 树中每一层结点的最大值称为树的宽度。
  • 如果树有n个结点,则有n-1条边。

3.树的遍历

  • 定义: 从根结点出发,按照某种次序访问树中所有结点,每个结点仅被访问一次。
  • 分类:
    ·前序遍历:根左右
    ·后序遍历:左右根
    ·层序遍历:从根结点开始,自上而下逐层遍历,同层从左到右逐个访问。

二、树的存储结构

1.双亲表示法

一维数组存储树的结点(一般层序存储),数组一个元素对应一个结点,每个数组元素记录结点数据信息和该结点双亲在数组的下标。

struct PNode
{
    char data;
    int parent;
};

该方法能方便的找到双亲,但是不好找孩子,可以在结构体中再加一个信息,即第一个孩子的下标。

2.孩子表示法

多重链表表示法。
法1:指针域的个数等于树的度。
缺点:会造成空间的浪费
法2:指针域个数等于结点的度
缺点:结点结构不一致,不好实现
法3:结点所有孩子构成一个单链表
如下图:

n个单链表共有n个头指针,这n个头指针又组成了一个线性表。

struct CTNode//孩子结点
{
    int child;
    CTNode *next;
};
struct CBNode//表头结点
{
    char data;
    CTNode *firstChild;
};

缺点:孩子好找,双亲不好找

3.孩子兄弟表示法

二叉链表表示法。
每个结点除数据域外,还设置了两个指针分别指向该结点的第一个孩子和右兄弟。

4.总结

顺序存储:双亲表示法,双亲、孩子表示法
链式存储:多重链表表示法,孩子链表表示法,孩子兄弟表示法。


二叉树

二叉树及二叉搜索树BST
Treap树
Splay树
线段树(一)
线段树(二)

一、二叉树的逻辑结构

1.定义

  • 二叉树: n(n>=0)个结点的有限集合,该集合或者为空集(空二叉树),或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树的二叉树构成。
    特点:
    ·每个结点最多有两棵子树
    ·二叉树是有序的,次序不能任意颠倒
    注意: 二叉树不等于度为2的树,二叉树必须分左右子树,树没有这个要求。
  • 特殊二叉树:
    ·斜树: 所有结点都只有左子树的二叉树称为左子树,所有结点都只有右子树的二叉树称为右子树,左子树与右子树统称为斜树。
    斜树特点:每层只有一个结点,斜树的结点个数等于深度。
    ·满二叉树: 所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上的二叉树。
    满二叉树特点:叶子只能出现在最下面一层,只有度为0和度为2的结点。
    满二叉树在同样深度的二叉树中结点个数最多,满二叉树在同样深度的二叉树中叶子结点个数最多。
    ·完全二叉树: 满二叉树最后一个结点开始,连续去掉任意个结点(可以不去)。
    完全二叉树特点:深度为k的完全二叉树在k-1层是满二叉树;叶子结点只能出现在最下两层,且最下层的叶子结点都集中在左侧连续的位置;度为一的结点最多有1个,只能有左孩子。

2.基本性质

  • 性质1:二叉树中,若叶子结点的个数为n0,度为2的结点个数为n2,则n0=n2+1。
  • 性质2:二叉树第i层上最多有2i-1个结点(i>=1)。
  • 性质3:一棵深度为k的二叉树中最多有2k-1个结点。
  • 性质4:具有n个结点的完全二叉树的深度为𠃊log2n𠃎 +1。
  • 性质5:对一棵具有n个结点的完全二叉树从1开始按层序编号,对于编号为i(1<=i<=n)的结点(简称结点i),
    如果i>1,则结点i的双亲的编号为𠃊i/2𠃎,否则是根结点无双亲。
    如果2i<=n,则结点i的左孩子的编号为2i,否则无左孩子。
    如果2i+1<=n,则结点i的右孩子的编号为2i+1,否则结点i无右孩子。

3.遍历

  • 前序遍历: 根左右
  • 中序遍历: 左根右
  • 后序遍历: 左右根
  • 层序遍历: 从根结点开始,自上而下逐层遍历,同层从左到右逐个访问。
  • ·如何确定唯一二叉树? 前序+中序 或 后序+中序。

    上图发现,叶子结点为GEF,在前中后序遍历的相对次序不变。

二、二叉树的存储结构

1.顺序存储

用一维数组存储二叉树中的结点,并且结点的存储位置即下标应能体现结点之间的逻辑关系即父子关系。

2.二叉链表

前序遍历:

void BiTree::PreOrder(BiNode *bt)
{
    if(bt==NULL)
        return;
    else {
        cout<<bt->data<<"\\t";
        PreOrder(bt->lchild);
        PreOrder(bt->rchild);
        }
}

中序遍历:

void BiTree::InOrder(BiNode *bt)
{
    if(bt==NULL)
        return;
    else {
        InOrder(bt->lchild);
        cout<<bt->data<<"\\t";
        InOrder(bt->rchild);
        }
} 

后序遍历:

void BiTree::PostOrder(BiNode *bt)
{
    if(bt==NULL)
        return;
    else {
        PostOrder(bt->lchild);
        PostOrder(bt->rchild);
        cout<<bt->data<<"\\t";
        }
}  

未完。。。

以上是关于树和二叉树学习笔记(21.10.26)的主要内容,如果未能解决你的问题,请参考以下文章

数据结构学习笔记——广义表以及树和二叉树的基本知识

数据结构学习笔记——广义表树和二叉树的基本知识

数据结构与算法学习笔记 树

数据结构与算法学习笔记 树

数据结构与算法学习笔记 树

期末复习笔记——树和二叉树