二叉树的三种遍历,包括递归与非递归,c++语言

本文详细介绍了二叉树的前序、中序和后序遍历方法,并提供了递归和非递归(使用栈)的多种实现方式,有助于深入理解二叉树遍历算法。

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

    二叉树的三种遍历

  首先,二叉树的三种遍历使用递归来解决非常简单。下面只给出代码。
  第二,如果不能使用递归来做,就要自己用queue或者stack这样的数据结构来实现递归的过程。
下面的代码是用stack来实现的。先序遍历用stack实现很简单,写了一种方法。中序遍历和后序遍历就要有点思考的过程了。
中序遍历我写了三种,后序遍历写了两种方法。
struct treenode {
		treenode *left, *right;
		int val;
		treenode(int x,treenode *l=nullptr,treenode *r=nullptr) { val = x;left = l;right = r; }
	};

//二叉树遍历用递归和非递归
	void preorderRecu(treenode *head,vector<int> &res) {
		if (head == nullptr)
			return;
		res.push_back(head->val);
		preorderRecu(head->left, res);
		preorderRecu(head->right, res);
	}
	void inorderRecu(treenode *head, vector<int> &res) {
		if (head == nullptr)
			return;
		inorderRecu(head->left, res);
		res.push_back(head->val);
		inorderRecu(head->right, res);
	}
	void postorderRecu(treenode *head, vector<int> &res) {
		if (head == nullptr)
			return;
		postorderRecu(head->left, res);
		postorderRecu(head->right, res);
		res.push_back(head->val);
	}
	void preorderStack(treenode *head, vector<int> &res) {
		if (head == nullptr) return;
		stack<treenode *> sta;
		sta.push(head);
		while (!sta.empty()) {
			treenode *out = sta.top();
			sta.pop();
			res.push_back(out->val);
			if (out->right) sta.push(out->right);
			if (out->left) sta.push(out->left);
		}
		return;
	}
	void inorderStack(treenode *head, vector<int> &res) {
		
		if (head == nullptr) return;
		stack<treenode *> sta;
		sta.push(head);
		while (!sta.empty()) {
			treenode *top = sta.top();
			while (top->left) {
				sta.push(top->left);
				top = top->left;
			}
			while (!sta.empty()) {
				top = sta.top();
				sta.pop();
				res.push_back(top->val);
				if (top->right) {
					sta.push(top->right);
					break;
				}
			}
		}
	}
	void inorderStack_2(treenode *head, vector<int> &res) {
		if (!head) return;
		stack<treenode *> sta;
		while (!sta.empty() || head) {
			if (head) {
				sta.push(head);
				head = head->left;
			}
			else {
				head = sta.top();
				sta.pop();
				res.push_back(head->val);
				head = head->right;
			}
		}
	}
	void inorderStack_3(treenode *head, vector<int> &res) {
		if (!head) return;
		stack<treenode *> s;
		s.push(head);
		//treenode *pre = nullptr;
		while (!s.empty()) {
			treenode *top = s.top();
			s.pop();
			if (!top->left && !top->right) {
				res.push_back(top->val);
				//pre = top;
			}
			else if (top->left && !top->right) {
				if (s.top() == nullptr) {
					s.pop();
					res.push_back(top->val);
				}
				else {
					s.push(nullptr);//用一个空指针来标志右孩子节点
					s.push(top);
					s.push(top->left);
				}
			}
			else if (!top->left && top->right) {
				if (s.top() == top->right) {
					res.push_back(top->val);
				}
				else {
					s.push(top->right);
					s.push(top);
				}
			}
			else {
				if (!s.empty()&&s.top() == top->right) {
					res.push_back(top->val);
				}
				else {
					s.push(top->right);
					s.push(top);
					s.push(top->left);
				}
			}
		}
	}
	void postorderStack(treenode *head, vector<int> &res) {
		//第一种方法 用两个栈 s2起收集作用 s1的压入弹出表示了遍历过程
		if (head == nullptr)
			return;
		stack<treenode *> s1, s2;
		s1.push(head);
		while (s1.empty() != true) {
			treenode *top = s1.top();
			s1.pop();
			s2.push(top);
			if (top->left) s1.push(top->left);
			if (top->right) s1.push(top->right);
		}
		while (!s2.empty()) {
			treenode *top = s2.top();
			s2.pop();
			res.push_back(top->val);
		}
	}
	void postorderStack_2(treenode *head, vector<int> &res) {
		if (!head) return;
		stack<treenode *> s;
		s.push(head);
		treenode *pre = nullptr;
		while (!s.empty()) {
			treenode *top = s.top();
			if (!top->left && !top->right) {
				s.pop();
				res.push_back(top->val);
				pre = top;
			}
			else {
				if (pre != nullptr && ((pre == top->left) || (pre == top->right))) {
					s.pop();
					res.push_back(top->val);
					pre = top;
				}
				else {
					if (top->right) s.push(top->right);
					if (top->left) s.push(top->left);
				}
			}
		}

	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值