层序遍历递归删除二叉树
什么是递归删除?
从叶节点开始向根节点的方向逐层删除。
直观的讲,对于以下二叉树,递归删除的次序为:f -> g -> h -> i -> d -> e -> b -> c -> a
递归删除一定要用递归算法吗?
不一定,你可以用递归算法实现递归删除,也可以用非递归算法实现递归删除;可以用非递归算法实现非递归删除,也可以用递归算法实现非递归删除。
简言之,递归删除的递归主要指的是删除的次序,而非删除算法是否递归。
非递归层序遍历实现递归删除
非递归层序需要队列辅助,进行递归删除需要栈的辅助。
二叉树链式存储结构描述:
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;
直观的看是这样:
层序遍历递归删除二叉树的使用辅助指针的递归实现(伪代码):
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