c++实现二叉树遍历(递归和非递归)

本文详细介绍了二叉树的遍历方法,包括递归和非递归两种方式。递归遍历简单直观,遵循前序、中序、后序的访问顺序;非递归遍历则利用栈来辅助实现,通过控制栈的操作来达到遍历的目的。

递归遍历

二叉树遍历的递归表示法非常简单,遵循遍历顺序即可

#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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值