Morris遍历

morris遍历原理参考此处:Morris遍历_六甲横宝的博客-CSDN博客_morris遍历

下面给出用morris遍历实现二叉树的前中后序遍历代码:

前序:

vector<int> morrisPreOrder(TreeNode *root) {
	vector<int> res;
	TreeNode *cur = root, *mostRight = nullptr;
	while (cur) {
		mostRight = cur->left;
		if (mostRight) { //左子树不为空,cur会到达两次
			while (mostRight->right&&mostRight->right != cur) {
				mostRight = mostRight->right;
			}
			if (mostRight->right == nullptr) {
				mostRight->right = cur;
				res.push_back(cur->val); //第一次到的时候打印
				cur = cur->left;
				continue;
			}
			else {  
				mostRight->right = nullptr;  //第二次到的时候不打印
			}
		}
		else { //左子树为空,cur只会到达一次
			res.push_back(cur->val);
		}
		// cur没有左子树或其左子树最右节点的right指针指向cur,均要将cur右移
		cur = cur->right; 
	}
	return res;
}

中序:

vector<int> morrisInOrder(TreeNode *root) {
	vector<int> res;
	TreeNode *cur = root, *mostRight = nullptr;
	while (cur) {
		mostRight = cur->left;
		if (mostRight) { //左子树不为空,cur会到达两次
			while (mostRight->right&&mostRight->right != cur) {
				mostRight = mostRight->right;
			}
			if (mostRight->right == nullptr) {
				mostRight->right = cur;
				cur = cur->left; //第一次到的时候不打印
				continue;
			}
			else {  
				res.push_back(cur->val); //第二次到的时候打印
				mostRight->right = nullptr;
			}
		}
		else { //左子树为空,cur只会到达一次
			res.push_back(cur->val);
		}
		// cur没有左子树或其左子树最右节点的right指针为cur,均要将cur右移
		cur = cur->right;
	}
	return res;
}

后序:

先右后左的前序遍历,再反转即得到后序遍历

//先右后左的前序遍历,反转后就是后序遍历
vector<int> morrisPostOrder(TreeNode *root) {
	vector<int> res;
	TreeNode *cur = root, *mostLeft = nullptr;
	while (cur) {
		mostLeft = cur->right;
		if (mostLeft) { //右子树不为空,cur会到达两次
			while (mostLeft->left&&mostLeft->left != cur) {
				mostLeft = mostLeft->left;
			}
			if (mostLeft->left == nullptr) {
				mostLeft->left = cur;
				res.push_back(cur->val);  //第一次到的时候打印
				cur = cur->right;
				continue;
			}
			else {
				mostLeft->left = nullptr; //第二次到的时候不打印
			}
		}
		else { //右子树为空,cur只会到达一次
			res.push_back(cur->val);
		}
		//cur右子树为空或者右子树最左节点的left指针为cur,均要将cur左移
		cur = cur->left;
	}
	reverse(res.begin(), res.end());  //反转
	return res;
}