树的创建与遍历详解

由于昨天面试字节跳动时挂在树的中序迭代遍历上,痛定思痛将树的创建及遍历代码从头到尾仔细写了一遍,至于为什么要把树的创建加进来嘛,一方面有时候笔试要求处理输入时可能会涉及到这块,另一方面没有树也没法进行后续遍历效果的验证,以上!!!

#include "pch.h"
#include <iostream>
#include"TreeNode.h"
#include<vector>
#include<queue>
#include<stack>
using namespace std;

//根据数组生成二叉树
TreeNode* creat_tree(vector<int>&record,int& index)
{
	if (record[index] == 0) {
		return nullptr;
	}
	TreeNode* root = new TreeNode(record[index]);
	root->left = creat_tree(record, ++index);
	root->right= creat_tree(record, ++index);
	return root;
}


//层序遍历
void levelorder(TreeNode* root) {
	queue<TreeNode*>q;
	q.push(root);
	while (!q.empty()) {
		TreeNode* tmp = q.front();
		q.pop();
		cout << tmp->val << " ";
		if (tmp->left) q.push(tmp->left);
		if (tmp->right) q.push(tmp->right);
	}
}

//先序遍历递归版
void preorder_recur(TreeNode*root) {
	if (root == nullptr) return;
	cout << root->val <<" ";
	preorder_recur(root->left);
	preorder_recur(root->right);
}


//中序遍历递归版
void inorder_recur(TreeNode*root) {
	if (root == nullptr) return;
	inorder_recur(root->left);
	cout << root->val << " ";
	inorder_recur(root->right);
}

//后序遍历递归版
void postorder_recur(TreeNode*root) {
	if (root == nullptr) return;
	postorder_recur(root->left);
	postorder_recur(root->right);
	cout << root->val << " ";
}


//先序遍历迭代版
void preorder_traverse(TreeNode*root) {
	stack<TreeNode*>s;
	s.push(root);
	while (!s.empty()) {
		TreeNode*node = s.top();
		s.pop();
		cout << node->val << " ";
		if (node->right)
			s.push(node->right);
		if (node->left)
			s.push(node->left);
	}
}

//中序遍历迭代版
void inorder_traverse(TreeNode*root) {
	stack<TreeNode*>s;
	TreeNode* p = root;
	while (p || !s.empty()) {
		if (p) {
			s.push(p);
			p = p->left;
		}
		else {
			TreeNode* node = s.top();
			s.pop();
			cout << node->val << " ";
			p = node->right;
		}
	}
}


//后续遍历迭代版
void postorder_traverse(TreeNode* root) {
	stack<TreeNode*> s;
	TreeNode*p = root;
	TreeNode*last_visit = nullptr;
	while (p || !s.empty()) {
		if (p) {
			s.push(p);
			p = p->left;
		}
		else {
			TreeNode * node = s.top();//到这步左节点已经访问过了
			s.pop();
			if (node->right == nullptr || node->right == last_visit) {//右节点为空或者已经访问过才能输出父节点
				cout << node->val << " ";
				last_visit = node;//每次输出节点值都更新上次访问这个指针,用来确定节点的左右子树是否都访问过
			}
			else {
				s.push(node);
				p = node->right;
			}

		}
	}
}



int main()
{
	//为了方便直接给一个数组,注释内容为交互式输入数组
	vector<int>record{ 1,2,0,3,0,0,4,5,0,0,6,0,0 };
	//int n;
	//cout<< "请输入节点个数" << endl;
	//cin >> n;
	//cout << "请输入节点值,0表示空节点" << endl;
	//int val;
	//while (n--) {
	//	cin >> val;
	//	record.push_back(val);
	//}

	int index = 0;
	TreeNode*root=creat_tree(record,index);

	cout <<endl<<"层序遍历结果:";
	levelorder(root);
	cout << endl;

	cout << endl<< "先序遍历结果:" ;
	preorder_recur(root);
	cout << "	";
	preorder_traverse(root);
	cout << endl;
	
	cout <<endl<<"中序遍历结果:" ;
	inorder_recur(root);
	cout << "	";
	inorder_traverse(root);
	cout << endl;

	cout << endl<<"后序遍历结果:" ;
	postorder_recur(root);
	cout << "	";
	postorder_traverse(root);
	cout << endl;


	return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值