数据结构——树

一、树

树是n(n≥0)个结点的有限集合。n=0时称为空树。在任意一棵非空树中:
(1)有且仅有一个特定的称为根(root)的结点;
(2)当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1,T2,…,Tm,其中每一个集合本身又有一棵树,并且称为根的子树。
结点拥有的子树数称为结点的度(degree)。度为0的结点称为叶结点(leaf)或终端结点;度不为0的结点称为非终端结点或分支结点。除根结点之外,分支结点也称为内部结点。树的度是树内各结点的度的最大值树中结点的最大层次称为树的深度(depth)或高度
如果将树中结点的各子树看成从左至右是有序的,不能互换的,则称该树为有序树,否则称为无序树。
森林(forest)是m(m≥0)棵互不相交的树的集合

树的存储结构的常用表示法是孩子表示法,即每个结点有多个指针域,其中每个指针指向一棵子树的根结点,即用多重链表来表示树
树的常见操作有
(1)初始化,建立一个空的树;
(2)销毁树;
(3)按照给定内容创建一棵树;
(4)将树中数据清空;
(5)判断树是否为空;
(6)获得树的深度;
(7)获得树的根结点;
(8)获得树中给定结点处的数据值;
(9)将树中给定结点处赋值为给定值;
(10)获得树的指定结点的父结点;
(11)获得树的指定结点的左孩子结点;
(12)获得树的指定结点的右孩子结点;
(13)在树中指定结点处插入给定值作为新的结点
(14)删除树中的指定结点
(15)查找在树的结点中是否有结点的数据值与给定值相等
(16)树的所有结点的顺序遍历

二、二叉树

普通树的操作是很复杂的,且没有良好的性质,一般不常用。常用的是树的一个特例,二叉树。
二叉树(binary tree)是n(n≥0)个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两棵互不相交的,分别称为根结点的左子树和右子树的二叉树组成。
在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上,这样的二叉树称为满二叉树
对一棵具有n个结点的二叉树按层序编号,如果编号为i(1≤i≤n)的结点与同样深度的满二叉树中编号为i的结点在二叉树中位置完全相同,则这棵二叉树称为完全二叉树
二叉树具有以下性质:
(1)在二叉树的第i层上至多有2^(i-1)个结点(i≥1)。
(2)深度为k的二叉树至多有2^k-1个结点(k≥1)。
(3)对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0=n2+1。
(4)具有n个结点的完全二叉树的深度为floor(log2N)+1。
(5)如果对一棵有n个结点的完全二叉树的结点按层序编号(从第1层到最后一层,每层从左到右),对任一结点i(1≤i≤n)有:
①如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲是结点floor(i/2);
②如果2i>n,则结点i无左孩子(结点i为叶子结点);否则其左孩子是结点2i;
③如果2i+1>n,则结点i无右孩子;否则其右孩子是结点2i+1。
二叉树一般用二叉链表表示,二叉链表的结点结构为:

template<typename T>
class Node
{
   
   
public:
    T data;
    Node *lchild, *rchild;
    Node(T _data)
    {
   
   
        data = _data;
        lchild = nullptr;
        rchild = nullptr;
    }
    ~Node()
    {
   
   
        if (lchild != nullptr)
        {
   
   
            delete lchild;
        }
        if (rchild != nullptr)
        {
   
   
            delete rchild;
        }
    }
};
template<typename T>
class BinaryTree
{
   
   
private:
    Node *root;
public:
    BinaryTree()
    {
   
   
        root = nullptr;
    }
    ~BinaryTree()
    {
   
   
        delete root;
    }
    void build_demo()
    {
   
   
        root = new Node(1);
        root->lchild = new Node(2);
        root->rchild = new Node(3);
        root->lchild->lchild = new Node(4);
        root->lchild->rchild = new Node(5);
        root->rchild->rchild = new Node(6);
    }
};

二叉树的常见创建方式有:

// 根据A(,C)形式的字符串构建二叉树
template<typename T>
Node<T> *str2Tree(const string &str)
{
   
   
    int len = str.length();
    if (len == 0)
    {
   
   
        return nullptr;
    }
    Node<T> *p = new Node<T>(str[0]);
    Node<T> *finalPtr = p;
    stack<Node<T>*> s;
    int state = 0;
    for (int i = 1; i < len; ++i)
    {
   
   
        switch (str[i])
        {
   
   
        case '(':
            s.push(p);
            state =
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值