二叉树的各种周游

本文探讨了如何周游二叉树,包括深度优先周游(DFS)的先序、中序、后序三种方式及其递归和非递归实现,特别是后序周游的非递归版本。同时介绍了广度优先周游(BFS)通过队列按层次访问节点的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[问题描述]:如何周游一棵二叉树。

二叉树的周游分为深度优先周游(DFS)和广度优先周游(BFS)。

对于深度优先周游,左中右的排列共有3!=6种,但是先访问右子树后访问左子树不符合人们的习惯,所以就剩下三种:先序(中左右),中序(左中右),后序(左右中)。每种周游都有递归和非递归实现,非递归是利用栈实现的。

后序周游的非递归版本稍微复杂点,因为访问完某个子树之后,还要判断是从哪个子树返回的。如果是左子树,还要访问完右子树,才能访问自己。

广度周游按照层数访问,先访问处于同样深度的节点,然后再访问下一层。广度周游借助队列实现。


#ifndef BITREE
#define BITREE

#include <stack>
#include <queue>
using std::stack;
using std::queue;

struct Node{
	char data;
	Node *left, *right;
	Node(char val = ' ', Node *l = NULL, Node *r = NULL) : data(val), left(l), right(r){}
};

typedef Node* BiTree;

// 先序周游(递归)
void PreOrder(Node* root){
	if(root != NULL){
		printf("%c", root->data);
		PreOrder(root->left);
		PreOrder(root->right);
	}
}
// 先序周游(非递归)
void PreOrder_NoRecursion(Node* root){
	stack<Node*> Stack;
	Node *p = root;

	while(!Stack.empty() || p){
		if(p){
			printf("%c", p->data);
			Stack.push(p);
			p = p->left;
		}
		else{
			p = Stack.top();
			Stack.pop();
			p = p->right;
		}
	}
}

// 中序周游(递归)
void InOrder(Node *root){
	if(root){
		InOrder(root->left);
		printf("%c", root->data);
		InOrder(root->right);
	}
}
// 中序周游(非递归)
void InOrder_NoRecursion(Node *root){
	stack<Node*> Stack;
	Node *p = root;
	while(!Stack.empty() || p){
		if(p){
			Stack.push(p);
			p = p->left;
		}
		else{
			p = Stack.top();
			printf("%c", p->data);
			Stack.pop();
			p = p->right;
		}
	}
}

// 后续周游(递归)
void PostOrder(Node *root){
	if(root){
		PostOrder(root->left);
		PostOrder(root->right);
		printf("%c", root->data);
	}
}


// 后续周游(非递归)
void PostOrder_NoRecursive(Node *root){
	stack<Node*> Stack;
	Node *p = root;
	Node *q = NULL;

	while(p || !Stack.empty()){
		while(p){
			Stack.push(p);
			p = p->left;
		}
		p = Stack.top();
		if(p->right == NULL || p->right == q){  //从右子树返回
			printf("%c", p->data);
			Stack.pop();
			q = p;
			p = NULL;
		}
		else{
			p = p->right;  //从左子树返回,访问右子树
		}
	}
}

// 广度优先周游
void LevelOrder(Node *root){
	queue<Node*> Queue;
	if(root)
		Queue.push(root);
	Node *p = NULL;

	while(!Queue.empty()){
		p = Queue.front();
		Queue.pop();
		printf("%c", p->data);
		if(p->left)
			Queue.push(p->left);
		if(p->right)
			Queue.push(p->right);
	}
}


Node* Find(Node *root, char val){
	if(!root){
		return NULL;
	}
	else{
		if(root->data == val)
			return root;
		else{
			Node *temp = Find(root->left, val);
			if(temp == NULL){
				temp = Find(root->right, val);
			}
			return temp;
		}
	}
}

void DestroyTree(Node *root){
	if(root){
		DestroyTree(root->left);
		DestroyTree(root->right);
		delete root;
	}
}
#endif


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值