递归遍历
二叉树遍历的递归表示法非常简单,遵循遍历顺序即可
#ifndef RECURSIVE_H_
#define RECURSIVE_H_
#include"construct_binary_tree.h"
#include<iostream>
using namespace std;
class RecurisveTree {
public:
RecurisveTree();
~RecurisveTree();
void PreTraverse(BinaryTree *T);
void MidTraverse(BinaryTree *T);
void EndTraverse(BinaryTree *T);
};
RecurisveTree::RecurisveTree() {
}
RecurisveTree::~RecurisveTree() {
}
//前序遍历
void RecurisveTree::PreTraverse(BinaryTree *T) {
if (T!=nullptr) {
cout << T->val << " "; //向访问根节点
PreTraverse(T->leftchild);//访问左子树
PreTraverse(T->rightchild);//访问右子树
}
}
//中序遍历
void RecurisveTree::MidTraverse(BinaryTree *T) {
if (T!=nullptr) {
MidTraverse(T->leftchild);
cout << T->val << " ";
MidTraverse(T->rightchild);
}
}
//后序遍历
void RecurisveTree::EndTraverse(BinaryTree *T) {
if (T!=nullptr) {
EndTraverse(T->leftchild);
EndTraverse(T->rightchild);
cout << T->val << " ";
}
}
#endif // !RECURSIVE_H_
非递归遍历
二叉树的非递归遍历更考验我们对二叉树这种结构的理解,其实非递归的实现方式也是采用递归的思想去完成,用栈这种数据结构去实现
#pragma once
#ifndef NODRECURSIVE_H_H
#define NODRECURSIVE_H_H
#include"construct_binary_tree.h"
#include<iostream>
#include<stack>
using namespace std;
class NonRecursive {
public:
void PreTraverse(BinaryTree *T);
void MidTraverse(BinaryTree *T);
void EndTraverse(BinaryTree *T);
};
/*对于任一结点cur:
1)访问结点cur,并将结点cur入栈;
2)判断结点cur的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点cur,循环至1);
若不为空,则将cur的左孩子置为当前的结点cur;
3)直到cur为NULL并且栈为空,则遍历结束。*/
void NonRecursive::PreTraverse(BinaryTree *T) {
stack<BinaryTree *> s;
BinaryTree *cur=T;
while (cur!=nullptr||!s.empty()) {
while (cur!=nullptr) {
cout << cur->val <<" ";
s.push(cur);
cur = cur->leftchild;
}
//涉及到pop的操作所以判定条件是栈不为空
if (!s.empty()) {
cur = s.top();
s.pop();
cur = cur->rightchild;
}
}
}
/*cur的左孩子置为当前的cur,然后对当前结点cur再进行相同的处理;
2)若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的cur置为栈顶结点的右孩子;
3)直到cur为NULL并且栈为空则遍历结束
*/
void NonRecursive::MidTraverse(BinaryTree *T) {
stack<BinaryTree *>s;
BinaryTree *cur = T;
while (cur!=nullptr||!s.empty()) {
while (cur!=nullptr) {
s.push(cur);
cur = cur->leftchild;
}
if (cur==nullptr) {
cur = s.top();
cout << cur->val << " ";
s.pop();
}
cur = cur->rightchild;
}
cout << endl;//回车换行
}
//思想: 一共有两种情况
//①节点同时没有左孩子和右孩子,说明是根节点,可以遍历然后出栈;
//②或者不是根节点但同时左孩子和右孩子被访问过,也可以遍历后出栈
void NonRecursive::EndTraverse(BinaryTree *T) {
stack<BinaryTree *> s;
BinaryTree *cur ;
BinaryTree *pre = nullptr;
s.push(T);
while (!s.empty()) {
cur = s.top();
if ((cur->leftchild==nullptr&&cur->leftchild==nullptr) //没有左孩子和右孩子了说明可以访问
|| (pre!=nullptr&& (pre==cur->leftchild||pre==cur->rightchild)) //存在子树同时左孩子和右孩子都被访问过了
) {
cout << cur->val<<" ";
s.pop();
pre = cur;
}
else {
//右孩子先入栈 左孩子后入栈
if (cur->rightchild!=nullptr) {
s.push(cur->rightchild);
}
if (cur->leftchild!=nullptr) {
s.push(cur->leftchild);
}
}
}
}
#endif // !NODRECURSIVE_H_H
construct_binary_tree.h文件
#ifndef BINARY_TREE_H
#define BINARY_TREE_H
#include<iostream>
struct BinaryTree
{
int val;
BinaryTree *leftchild;
BinaryTree *rightchild;
BinaryTree(int x):val(x),leftchild(nullptr),rightchild(nullptr){}
};
BinaryTree * ConstructBinaryTree() {
BinaryTree *A = new BinaryTree(1);// 根节点
BinaryTree *B = new BinaryTree(2);
BinaryTree *C = new BinaryTree(4);
BinaryTree *D = new BinaryTree(7);
BinaryTree *E = new BinaryTree(3);
BinaryTree *F = new BinaryTree(5);
BinaryTree *G = new BinaryTree(6);
BinaryTree *H = new BinaryTree(8);
A->leftchild = B;
A->rightchild = E;
B->leftchild = C;
C->rightchild = D;
E->leftchild = F;
E->rightchild = G;
G->leftchild = H;
return A;
}
#endif // !1
本文详细介绍了二叉树的遍历方法,包括递归和非递归两种方式。递归遍历简单直观,遵循前序、中序、后序的访问顺序;非递归遍历则利用栈来辅助实现,通过控制栈的操作来达到遍历的目的。
&spm=1001.2101.3001.5002&articleId=108651645&d=1&t=3&u=330dc192270d419ebeb689669382799a)
5903

被折叠的 条评论
为什么被折叠?



