实验七 二叉树的创建与遍历(第10周)

wuchangjian2021-11-14 21:28:08编程学习

实验目的:

  通过上机实验进一步掌握栈、队列、二叉树的存储结构及基本操作的实现方法。

实验内容与要求:

  基于二叉链表存储结构实现二叉树的基本运算,要求:

  ⑴能建立非空二叉树;

  ⑵实现二叉树的先、中、后序递归遍历算法;

  ⑶实现二叉树的非递归的先(或中、或后)序遍历算法及层序遍历算法;

  ⑷记录运行结果并对递归算法和非递归算法的效率加以分析。

第四点未实现。

注意:

在先序输入创建上述二叉树时应输入:AB##CDF##G##E##

(每个叶子节点后都需两个#字符来表示它们是叶子节点)

 而不是:ABCDFGE.

#include<iostream>
#include<vector>
#include<stack>
#include<queue>
using namespace std;

template<typename T>
class BinTree {
private:
	struct BinNode {
		T data;		//数值
		struct BinNode* lchild, * rchild;	//左右孩子指针
	};
	BinNode* root;	//根节点
	vector<T>res;	//记录先序、中序、后序遍历的结果

public:
	//初始化
	BinTree() {
		root =NULL;
	}

	//以先序输入创建二叉树,若树为空则输入#字符(注意:叶子节点后面需跟两个#字符)
	BinNode *init() {
		BinNode* p = NULL;
		T n;				//存放临时数据	
		cin >> n;
		if (root == NULL) {
			root = new BinNode;
			root->data = n;
			root->lchild = init();
			root->rchild = init();
		}
		else {
			if (n == '#')return NULL;
			else {
				p = new BinNode;
				p->data = n;
				p->lchild = init();
				p->rchild = init();
				return p;
			}
		}
		return NULL;
}

	//先序递归遍历
	vector<T>first_recursion(BinNode *root) {
		if (root != NULL) {
			res.push_back(root->data);
			first_recursion(root->lchild);
			first_recursion(root->rchild);
		}
		return res;
	}

	//中序递归遍历
	vector<T>middle_recursion(BinNode* root) {
		if (root != NULL) {
			middle_recursion(root->lchild);
			res.push_back(root->data);
			middle_recursion(root->rchild);
		}
		return res;
	}

	//后序递归遍历
	vector<T>after_recursion(BinNode* root) {
		if (root != NULL) {
			after_recursion(root->lchild);
			after_recursion(root->rchild);
			res.push_back(root->data);
		}
		return res;
	}

	//先序非递归,利用栈实现
	vector<T>first_non_recursion(BinNode* root) {
		if (root == NULL) {
			return res;
		}
		stack<BinNode*>st;
		st.push(root);
		while (!st.empty()) {
			auto m = st.top();
			st.pop();
			res.push_back(m->data);
			
			//因为栈的后进先出,所以先序遍历先压右节点再压左节点
			if (m->rchild) {
				st.push(m->rchild);
			}
			if (m->lchild) {
				st.push(m->lchild);
			}
		}
		return res;
	}

	//中序非递归,利用栈实现
	vector<T>middle_non_recursion(BinNode* root) {
		stack<BinNode*>st;
		while (!st.empty() || root) {
			while (root) {
				st.push(root);
				root = root->lchild;
			}
			if (!st.empty()) {
				root = st.top();
				st.pop();
				res.push_back(root->data);
				root = root->rchild;		//判断当前节点是否有右孩子;
			}
		}
		return res;
	}

	//后序非递归,利用先序非递归结果,只需先序遍历时先进栈左节点后进栈右节点,然后逆置即可
	vector<T>after_non_recursion(BinNode* root) {
		if (root == NULL) {
			return res;
		}
		stack<BinNode*>st;
		st.push(root);
		while (!st.empty()) {
			auto m = st.top();
			st.pop();
			res.push_back(m->data);

			//此时先压左节点,再压右节点
			if (m->lchild) {
				st.push(m->lchild);
			}
			if (m->rchild) {
				st.push(m->rchild);
			}
		}
		//结果逆置
		reverse(res.begin(),res.end());
		return res;
	}

	//层次遍历,利用队列实现
	vector<T>level_recursion(BinNode* root) {
		queue<BinNode*>que;
		if (root == NULL)return res;
		que.push(root);
		while (!que.empty()) {
			auto x = que.front();
			res.push_back(x->data);
			que.pop();
			if (x->lchild != NULL) {
				que.push(x->lchild);
			}
			if (x->rchild != NULL) {
				que.push(x->rchild);
			}
		}
		return res;
	}


	//将遍历结果传递给res
	vector<T>out(int n) {
		vector<T>().swap(res);
		//先序递归
		if (n == 1) {
			res = first_recursion(root);
		}
		//先序非递归
		if (n == -1) {
			res = first_non_recursion(root);
		}

		//中序递归
		else if(n==2){
			res = middle_recursion(root);
		}
		//中序非递归
		else if (n == -2) {
			res = middle_recursion(root);
		}

		//后序递归
		else if (n == 3) {
			res = after_recursion(root);
		}
		//后序非递归
		else if (n == -3) {
			res = after_non_recursion(root);
		}

		//层次遍历
		else if (n == 4) {
			res = level_recursion(root);
		}

		return res;
	}
	
};

int main() {
	BinTree<char>T;
	cout << "以先序输入创建二叉树,若树为空则输入#字符(注意:叶子节点后面需跟两个#字符):"<<endl;
	T.init();
	vector<char>a;
	cout << endl << endl;

	cout << endl<<"先序递归:";
	vector<char>().swap(a);
	a = T.out(1);
	for (unsigned int i = 0; i < a.size(); i++) {
		cout << a[i];
	}
	cout << endl << "中序递归:";
	vector<char>().swap(a);
	a = T.out(2);
	for (unsigned int i = 0; i < a.size(); i++) {
		cout << a[i];
	}
	cout << endl << "后序递归:";
	vector<char>().swap(a);
	a = T.out(3);
	for (unsigned int i = 0; i < a.size(); i++) {
		cout << a[i];
	}

	cout << endl << endl;
	cout << endl << "先序非递归:";
	vector<char>().swap(a);
	a = T.out(-1);
	for (unsigned int i = 0; i < a.size(); i++) {
		cout << a[i];
	}
	cout << endl << "中序非递归:";
	vector<char>().swap(a);
	a = T.out(-2);
	for (unsigned int i = 0; i < a.size(); i++) {
		cout << a[i];
	}
	cout << endl << "后序非递归:";
	vector<char>().swap(a);
	a = T.out(-3);
	for (unsigned int i = 0; i < a.size(); i++) {
		cout << a[i];
	}
	
	cout << endl;
	cout << endl << "层次遍历";
	vector<char>().swap(a);
	a = T.out(4);
	for (unsigned int i = 0; i < a.size(); i++) {
		cout << a[i];
	}
	cout << endl << endl;
}

相关文章

Cocos Creator 3.3中的NodePool(节点池)

引擎版本:3.3 不知为何,我在官方的3.3版文档和3.3...

JetpackCompose-列表的使用

在Jetpackcompose中使用列表要是用LazyColumn和item @...

国家电影局:将开展电影惠民消费季,发放1亿元观影消费券

国家电影局:将开展电影惠民消费季,发放1亿元观影消费券

2022-08-11 20:32:47 8月11日,国家电影局官网发布...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。