树(C++)从小白开始(上)

本文介绍了树的概念,作为一对多关系的抽象数据结构,特别强调了二叉树的重要性和其定义。二叉树分为左子树和右子树,并有完全二叉树、斜二叉树和满二叉树等类型。接着,文章详细讲解了二叉树的先序、中序、后序遍历,以及非递归中序遍历和层序遍历的方法,同时探讨了二叉树的高度计算。这是一个关于二叉树基础知识的入门教程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先引入树的概念,在链表中我们讨论的是一对一的线性结构,而在生活中,我们有很多一对多的情况需要处理,所以引入了树的概念。

树是n个结点的有限集,n=0的时候成为空树,在任意一课非空树中,有且仅有一个特定的点称为根(root)的结点,当n>1时,其余结点可以分为M个互不相交的有限集T1,T2....,其中每一个有限集本身又是一颗树,并且称为根的字数。

而二叉树,则是一种特别重要的树的类型

二叉树则是有穷节点的集合,可以为空,由根节点和称为其左子树和右子树的结点的两个不相交的二叉树组成, 二叉树的子树有左右之分

二叉树中又有特殊的完全二叉树,斜二叉树,完美二叉树(满二叉树)

二叉树的定义

struct BiTNode
{
   ElemType data;
   BiTNode *lchild,*rchild;
}*BiTree;

这里插一句题外话在定义数据结构时 

*BiTree 等价于  typedef BiTNode *BiTree;

类似于 int *a;

二叉树的先序遍历

bool PreOrderTraverse(BiTree &T) //BiTree &T 等价于 BiTNode *&T;这是一个指向指针的引用
{
    if(T==NULL)
{
    return true;
}
    vist(T); //访问根节点
    PreOrderTraverse(T->lchild); //递归访问左孩子
    PreOrderTraverse(T->rchild);
    return true;
}

我们需要了解递归的基本思想 就很好理解上面这个代码了  在判断T不为空后,访问现在的根节点,然后传入T的左孩子,在判断T为不为空,访问节点,再传入左孩子,直到传入T->lchild为空则返回上一层。

二叉树的中序遍历

bool PreOrderTraverse(BiTree &T)
{
    if(T==NULL)
{
    return true;
}
    
    PreOrderTraverse(T->lchild); //递归访问左孩子
    vist(T); //访问根节点
    PreOrderTraverse(T->rchild);
    return true;
}

二叉树的后序遍历

bool PreOrderTraverse(BiTree &T)
{
    if(T==NULL)
{
    return true;
}
    
    PreOrderTraverse(T->lchild); //递归访问左孩子
    PreOrderTraverse(T->rchild);
    vist(T); //访问根节点
    return true;
}

三种算法的时间复杂度 O(n),空间复杂度O(n). 

非递归中序遍历

void InOrderTraversal(BinTree &T)
{
   //创建一个堆栈
    SqStack s;
    InitSqStack(S); //初始化
    BiTree p = T;
    while( p || !IsEmpty(S))
    {
        if(p)  
        { 
            Push(S, p); //一直向左沿途压入堆栈
            p = p->lchild;
        }
        else
        {
            Pop(S, p); //弹出栈
            visit(p);  //打印结点
            p = p->rchild;   //访问节点右孩子
         }
    }

}

二叉树的层序遍历 

//1. 根节点入队
//2. 从队列中取出一个元素
//3. 访问该元素的结点
//4. 若该元素所指的左右孩子不为空,则将其左右孩子的指针顺序入队

void LevelOrderTraversal(BiTree &T)
{
    SqQueue Q;
   InitsqQueue(Q);
  if(!T)
{
return;  //若是空直接返回
}
   BiTree p;
   PushQueue(Q,T);
   while(!QueueEmpty(Q))
{
   //将根节点出队
   DeQueue(Q,p);
 //访问根结点
        cout << p->data << endl;
        //if判断,是否能将根结点的左右孩子进队
        if (p->lchild != nullptr)
        {
            PushQueue(Q, p->lchild);
        }
        if (p->rchild != nullptr)
        {
            PushQueue(Q, p->rchild);
        }
}
}

二叉树的遍历 :输出二叉树的叶子结点

bool PreOrderTraverse(BiTree &T) //我们这里只需要判断是否有左右孩子结点才输出
{
    if(T==NULL)
{
    return true;
}
    if(!T->lchild &&! T->rhild)
{
vist(T); //访问根节点
}
    PreOrderTraverse(T->lchild); //递归访问左孩子
    PreOrderTraverse(T->rchild);
    return true;
}

二叉树的高度

int Depth(BiTree &T)
{
    if(T == nullptr)
    {
        return 0;
    }
    int m = Depth(T->lchild);
    int n = Depth(T->rchild);
    if(m>n)
        return m+1;
    else
        return n+1;
}

未完待续........... 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值