《数据结构》学习记录(9):二叉树

一、概念

1、二叉树的递归定义

二叉树是有限的结点集合,这个集合:

  • 或者是空;
  • 或者由一个根结点和两棵互不相交的称为左子树和右子树的二叉树组成。   

2、满二叉树

所有分支结点都有双分结点,并且叶结点都集中在二叉树的最下一层。 

3、完全二叉树

最多只有下面两层的结点的度数小于2,且最下面一层的叶结点都依次排列在该层最左边的位置上。 

二、二叉树的顺序存储结构

三、二叉树的链式存储结构

四、二叉树基本运算

1、定义二叉树结点

struct BTNode
{
    QChar data;
    BTNode * lchild{nullptr};
    BTNode * rchild{nullptr};
};

2、创建二叉树

//创建二叉树
void CreateBTNode(BTNode * & root,QString binaryTreeBracketNotationString)
{
    root = nullptr;
    enum class processTreeType//当前字符处理的类型
    {
        leftChildTree,
        rightChildTree,
        noChildTree
    };
    processTreeType nowNodeProcessTreeType{processTreeType::noChildTree};

    BTNode * currentNode{nullptr};//当前创建的结点
    QStack<BTNode*> stack;
    for(const auto & element : qAsConst(binaryTreeBracketNotationString))
    {
        if(element == '(')//表示一棵左子树的开始,即将前面刚创建的结点作为双亲结点进栈
        {
            stack.push(currentNode);
            nowNodeProcessTreeType = processTreeType::leftChildTree;
        }
        else if(element == ')')//表示一棵子树的结束
        {
            stack.pop();
        }
        else if(element == ',')//表示一棵右子树的开始
        {
            nowNodeProcessTreeType = processTreeType::rightChildTree;
        }
        else//字母,说明应该创建一个结点
        {
            currentNode = new BTNode;
            currentNode->data = element;

            if(!root)
                root = currentNode;
            else
            {
                switch (nowNodeProcessTreeType)
                {
                    case processTreeType::leftChildTree:stack.top()->lchild = currentNode;break;
                    case processTreeType::rightChildTree:stack.top()->rchild = currentNode;break;
                    case processTreeType::noChildTree:;break;
                }
            }
        }
    }
}

3、销毁二叉树

//递归销毁二叉树
void DestroyBT(BTNode * & node)
{
    if (!node)
        return;
    else
    {
        DestroyBT(node->lchild);
        DestroyBT(node->rchild);
        delete node;
        node = nullptr;
    }
}

4、查找结点

//递归查找结点
const BTNode * findNode(const BTNode * node,const QChar & c)
{
    if (!node)
        return nullptr;
    else if (node->data == c)
        return node;
    else
    {
        if (const BTNode * p = findNode(node->lchild,c))
            return p;
        else
            return findNode(node->rchild,c);
    }
}

5、求高度

//递归求高度
int BTNodeDepth(BTNode * node)
{
    if (!node)
        return 0; 	//空树的高度为0
    else
    {
        int lchilddep = BTNodeDepth(node->lchild);	//左子树的高度
        int rchilddep = BTNodeDepth(node->rchild);	//右子树的高度
        return lchilddep > rchilddep ? lchilddep + 1 : rchilddep + 1;
    }
}

6、输出二叉树的括号形式

//输出二叉树的括号形式
void DispBTNode(BTNode * node)
{
    if (node)
    {
        std::cout<<node->data.toLatin1();
        if (node->lchild || node->rchild)
        {
            std::cout<<"(";
            DispBTNode(node->lchild); //递归处理左子树
            if (node->rchild)
                std::cout<<",";
            DispBTNode(node->rchild); //递归处理右子树
            std::cout<<")";
        }
    }
}

7、使用

    QString binaryTreeBracketNotationString = "A(B(D(,G)),C(E,F))";
    BTNode * root;
    CreateBTNode(root,binaryTreeBracketNotationString);
    qDebug()<<BTNodeDepth(root);
    DispBTNode(root);
    DestroyBT(root);
    std::cout<<std::endl;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值