自己整理记忆 二叉树的遍历及应用

前言

二叉树这种数据结构虽然能有特点的保存数据,比如二叉搜索树(一种树,左节点小于根节点,右节点大于根节点)和平衡二叉树(二叉搜索树的升级,为了保证搜索树不失去平衡,变成链表,所以规定左右子树高度差不能超过1),但是操作起来就有难度了,要找一个数据或者插入删除,如何找到我们想找到的数据或者位置呢?由于非线性,所以遍历起来要按照一定的规则,保证每个结点被访问且只被访问一次,其实就是把非线性结构变成线性,这里用下图所示树来介绍前中后序三种遍历方法。
在这里插入图片描述

二叉树的存储结构

typedef struct BiTNode{
    ElemType data;//数据
    struct BiTNode *lchild,*rchild;//指针
}BiTnode,*BiTree;

先序遍历

如果树空返回NULL,否则按照 根结点->左子树->右子树 的顺序来遍历,代码实现如下

void PreOrderTraverse(BiTree T){//只用打印,所以传进来值就行,不用传地址
    if(T){//树不空
       cout<<T->data;//输出根节点
       PreOrderTraverse(T->lchild);//遍历左子树,直到左子树递归完才出来
       PreOrderTraverse(T->rchild);//遍历右子树,直到右子树递归完才出来
    }
}

按照先序遍历遍历上图所示的树,得到访问次序为:ABDEHIJKCFG

中序遍历

如果树空返回NULL,否则按照 左子树->根结点->右子树 的顺序来遍历,代码实现如下

void InOrderTraverse(BiTree T){//只用打印,所以传进来值就行,不用传地址
    if(T){//树不空
       InOrderTraverse(T->lchild);//遍历左子树,直到左子树递归完才出来
       cout<<T->data;//输出根节点
       InOrderTraverse(T->rchild);//遍历右子树,直到右子树递归完才出来
    }
}

按照先序遍历遍历上图所示的树,得到访问次序为:DBHEJIKAFCG

后序遍历

如果树空返回NULL,否则按照 根结点->左子树->右子树 的顺序来遍历,代码实现如下

void PastOrderTraverse(BiTree T){//只用打印,所以传进来值就行,不用传地址
    if(T){//树不空
       PastOrderTraverse(T->lchild);//遍历左子树,直到左子树递归完才出来
       PastOrderTraverse(T->rchild);//遍历右子树,直到右子树递归完才出来
       cout<<T->data;//输出根节点
    }
}

按照先序遍历遍历上图所示的树,得到访问次序为:DHJKIEBFGCA

应用

先序遍历的顺序建立二叉链表

//申请节点空间T,赋值ch
//递归建立左右子树
void CreatBiTree(BiTree &T){//建立新树,所以传进来地址,之后在此地址上进行操作
    cin>>ch;
    if(ch=='#') T=NULL;
    else{
        T=new BiTNode;
        T->data=ch;
        CreatBiTree(T->lchild);
        CreatBiTree(T->rchild);
    }
}

例如ABC##DE#G##F###
按照上述代码建立如下树
在这里插入图片描述

先序复制二叉树

void Copy(BiTree T,BiTree &NewT){
    if(T==NULL){//树空,直接返回
        NewT=NULL;
        return ;
    }else{
        NewT=new BiTNode;//申请结点
        NewT->data=T->data;//复制值
        Copy(T->lchild,NewT->lchild);//递归复制左子树
        Copy(T->rchild,NewT->rchild);//递归复制右子树
    }
}

后序计算二叉树深度

int dep(BiTree T){
    if(T==NULL) return 0;//相当于所有的叶子结点深度是1
    else{
        m=dep(T->lchild);
        n=dep(T->rchild);
        if(m>n)return (m+1);
        else return (n+1);
    }
}

统计结点个数

int Count(BiTree T){
    if(T==NULL) return 0;
    else return (Count(T->rchild)+Count(T->lchild)+1);//叶子结点是1,往上加
}

在这里插入图片描述

统计度为2的结点

Status PreOrderTraverseTree(BiTree t)
{
	if(t!=NULL)
	{
		if(t->lchild&&t->rchild)i++;//左右都不空
		PreOrderTraverseTree(t->lchild);
		PreOrderTraverseTree(t->rchild);
	}return Ok;
}

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值