有没有玩过空间复杂度O(1)的二叉树中序遍历

二叉树的中序遍历,时间复杂度为O(N),空间复杂度为O(1)。

这种遍历就是Morris遍历。这种遍历的实质是避免使用栈结构,而是让下层到上层有指针,具体是通过让底层节点指向nullptr的空闲指针指回上层的某个节点,从而完成下层到上层的移动。

可分为两个步骤:

  • 第一步骤
  1. 设当前字数的头结点为HeadNode,让HeadNode的左子树中最右节点的right指针指向HeadNode,
  2. 然后HeadNode的左子树继续执行步骤1的处理过程,直至遇到某一个节点没有左子树时记为Node,进入下一步骤
  • 第二步骤
  • 从Node开始通过每个节点的right指针进行移动,并且依次打印。设移动到的节点为curNode,对每个curNode节点都进行判断curNode节点的左子树中最右节点是否指向curNode
  1. 如果指向,将最右节点的right指针指向nullptr(恢复树的原状),打印curNode,继续通过curNode的right指针移动到下一个节点,重复第二步骤
  2. 如果没有,以curNode为头的子树执行第一步骤。

 我们可以通过下面的图片展示的过程来理解上面两个步骤

 代码验证:

#include<iostream>

using namespace std;

struct TreeNode{
	TreeNode* left;
	TreeNode* right;
	char value;
};
// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
TreeNode* BinaryTreeCreate(char* a, int* Index)
{
	TreeNode* root = (TreeNode*)malloc(sizeof(TreeNode));
	if (a[*Index] == '#')
		return NULL;

	root->value = a[*Index];
	++(*Index);
	root->left = BinaryTreeCreate(a, Index);
	++(*Index);
	root->right = BinaryTreeCreate(a, Index);
	return root;
}
void inorderTraversal(TreeNode* root)
{
	if (root == nullptr)
	{
		return;
	}
	TreeNode* Node1 = root;
	TreeNode* Node2 = nullptr;
	while (Node1 != nullptr)
	{
		//指向左子树
		Node2 = Node1->left;
		if (Node2 != nullptr)
		{
			//找左子树的最右节点
			while (Node2->right != nullptr&&Node2->right != Node1)
			{
				Node2 = Node2->right;
			}
			//如果最右节点指向空,将最右节点的右指针指向Node1(即该子树的根节点)
			if (Node2->right == nullptr)
			{
				Node2->right = Node1;
				Node1 = Node1->left;
				continue;
			}
			else 

			{
               //(Node2->right == Node1)
 //如果最右节点的右指针指向Node1,即将该子树遍历完毕,将右指针指向nullptr(恢复原状)
				Node2->right = nullptr;

			}
			
		}
		//cout << (Node1->value) << " " << endl;
		printf("%c ", Node1->value);
		Node1 = Node1->right;
		
	}
	cout << endl;
}
int main()
{
	char* a = "ABD##E#H##CF##G##";
	int Index = 0;
	TreeNode* root = BinaryTreeCreate(a, &Index);
	inorderTraversal(root);


	return 0;
}

代码中所构造的二叉树:

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值