首页 > 其他分享 >层序遍历递归删除二叉树

层序遍历递归删除二叉树

时间:2022-10-16 09:44:50浏览次数:58  
标签:遍历 辅助 递归 删除 层序 二叉树

层序遍历递归删除二叉树

什么是递归删除?

从叶节点开始向根节点的方向逐层删除。

直观的讲,对于以下二叉树,递归删除的次序为:f -> g -> h -> i -> d -> e -> b -> c -> a

001

递归删除一定要用递归算法吗?

不一定,你可以用递归算法实现递归删除,也可以用非递归算法实现递归删除;可以用非递归算法实现非递归删除,也可以用递归算法实现非递归删除。

简言之,递归删除的递归主要指的是删除的次序,而非删除算法是否递归。

非递归层序遍历实现递归删除

非递归层序需要队列辅助,进行递归删除需要栈的辅助。

二叉树链式存储结构描述:

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

层序遍历递归删除二叉树的非递归实现(伪代码):

void LevelOrder(BiTree T){
    InitQueue(Q); // 初始化辅助队列
    InitStack(S); // 初始化辅助栈
    BiTree p;
    EnQueue(Q, T); // 根节点入队
    while(!EmptyQueue(Q)){
        DeQueue(Q, p); // 层序出队
        Push(S, p); // 层序入栈
        if(p->rchild != null) // 左子树不空则左孩子进栈
            EnQueue(Q, p->rchild);
        if(p->lchild != null) // 右子树不空则右孩子进栈
            EnQueue(Q, p->lchild);
    }
    while(!EmptyStack(Q)){ // 递归序删除
        Pop(S, p);
        free(p);
    }
}

递归层序遍历实现递归删除

我认为单纯的递归层序是无法实现递归删除的。纯递归层序无法传递兄弟树的信息,一定要借助某些辅助结构,例如:使用辅助栈或使用辅助指针。

使用辅助栈

二叉树链式存储结构描述同上,不再赘述。

层序遍历递归删除二叉树的使用辅助栈的递归实现(伪代码):

void LevelOrder(BiTree T, int level, DynamicArray A[]){
    if(T == null) return; // 递归退出条件
    if(level > A.length) // 如果是新的一层则为该层新增一个栈
        PushBack(InitStack(S));
    Push(A[level], T); // 入对应层的栈
    LevelOrder(T->rchild, level+1); // 递归处理右子树
    LevelOrder(T->lchild, level+1); // 递归处理左子树
}

void deleteBiTree(BiTree T){
    InitDynamicArray(A); // 初始化辅助动态数组
    LevelOrder(T, 1);
    for(int i = A.length - 1; i >= 0; i--){ // 递归序删除
        while(!EmptyStack(A[i])){
            Pop(S, p);
            free(p);
        }
    }
}

使用辅助指针

这个思路是为了解决无法跳转到层序后续节点的问题,给每个节点添加一个指针指向层序后续节点,此时二叉树链式存储结构描述:

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

直观的看是这样:

001

层序遍历递归删除二叉树的使用辅助指针的递归实现(伪代码):

void LevelOrder(BiTree T){
    if(T == null) return;
    LevelOrder(T->next);
    free(T);
}

不过这样有个小瑕疵,还是自下向上删除的,但每层的删除顺序是倒着的:i -> h -> g -> f -> e -> d -> c -> b -> a

标签:遍历,辅助,递归,删除,层序,二叉树
From: https://www.cnblogs.com/AncilunKiang/p/16795663.html

相关文章

  • 字符串遍历器
    1.字符串可以通过for...of进行遍历字符.2.遍历器可以识别大于0xFFFF的码点,传统的for无法识别这样的码点lettext=String.fromCodePoint(0x20BB7);for(leti=0;i<......
  • 树与二叉树
    二叉树性质:度为0的节点比度为2的节点多一个。解释:度为1的节点均可忽略;度为2的节点就相当于分割点,而度为0的节点就相当于线段;不分割时即有一条线段,当每多一个分割点时,线段......
  • 广义表转二叉树
    前序遍历和中序遍历&后序遍历和中序遍历可以还原出唯一的二叉树,而前序遍历和后序遍历不行(满二叉树时貌似可以,但只有一个根节点和一个子孩子时一定不行)//输入:A(B(,D),......
  • 数据结构:二叉树
    定义特点每个节点最多有两棵子树,所以二叉树中不存在度大于2的节点。左子树和右子树是有区别的,次序不能颠倒。即使某个节点只有1个子节点,也是有左右之分的。特殊的......
  • 创建一个存储学生对象的集合,存储多个学生对象,使用程序实现在控制台遍历该集合
    学生类(需要重写hashCode()和equals())packagepackage7;importjava.util.Objects;publicclassStudent{privateStringname;privateintage;public......
  • 114. 二叉树展开为链表
    题目描述给你二叉树的根结点root,请你将它展开为一个单链表:展开后的单链表应该同样使用TreeNode,其中right子指针指向链表中下一个结点,而左子指针始终为null。展......
  • 二叉树(存储结构,三种遍历方式,构建树)——C语言描述
    二叉树(存储结构,三种遍历方式,构建树)——C语言描述目录二叉树(存储结构,三种遍历方式,构建树)——C语言描述0测试用例框架1定义2特殊二叉树3二叉树的性质4二叉树存储结构5......
  • List集合存储学生对象用三种方式遍历
    packagepackage5;importpackage4.Student;importjava.util.ArrayList;importjava.util.Iterator;importjava.util.List;//List集合存储学生对象用三种方式遍......
  • 226. 翻转二叉树
    题目描述解题思路二叉树的题一般都有对应的模板,我们做题时可以参考对应模板二叉树解题的思维模式分两类:1、是否可以通过遍历一遍二叉树得到答案?如果可以,用一个trav......
  • 617. 合并二叉树
    /***Definitionforabinarytreenode.*structTreeNode{*intval;*TreeNode*left;*TreeNode*right;*TreeNode():val(0),left(......