C++实现二叉树的非递归遍历

        在前面C++实现二叉树的递归遍历(详细步骤与代码实现)我们实现二叉树通过递归遍历实现了先序、中序与后续遍历,那么如何通过非递归遍历实现先序、中序与后续遍历呢?我们先看看非递归遍历规则。

还是同样的二叉树

1、首先将二叉树根节点A放入栈中,并将节点是否打印标签设为false。

2、再将节点A从栈中弹出,将其左右子树节点BF入栈,打印标签设为false,将A再次入栈,此时是否打印的标签设为true(注意这里三个节点入栈顺序与先序、中序与后续遍历方式有关,入栈顺序与遍历顺序正好相反,如果为先序遍历DLR,入栈顺序就应该为RLD)

3、再从栈中取出栈顶元素,重复2的步骤,本身与左右子树分别入栈,本身打印标签改为true,左右子树打印标签设为false。

4、如果从栈中取出的栈顶元素打赢标签为true,则直接打印,并取下一个栈中元素。

下面是具体实现的代码:

1、栈的定义与操作

//栈的定义与操作
//节点
class linknode
{
public:
	linknode* next;
};
//自定义数据
class my_data
{
public:
	linknode* node;
	char data;
};
//链式栈
class linkstack
{
public:
	linknode head;
	int size;
};
//初始化栈
linkstack* init_linkstack()
{
	linkstack* stack=new linkstack;
	stack->head.next=NULL;
	stack->size=0;
	return stack;
}
//入栈
void push_linkstack(linkstack* stack,linknode* data)
{
	data->next=stack->head.next;
	stack->head.next=data;
	stack->size++;
}
//出栈
void pop_linkstack(linkstack* stack)
{
	stack->head.next=stack->head.next->next;
	stack->size--;
}
//返回栈顶元素
linknode* top_linkstack(linkstack* stack)
{
	return stack->head.next;
}

2、二叉树相关定义与操作

//二叉树相关定义与操作
const int my_true=1;
const int my_false=0;
//定义二叉树节点
class binarynode
{
public:
	char ch;			 //节点数据域
	binarynode* lchild;  //左孩子
	binarynode* rchild;  //右孩子
};
//栈中的二叉树节点
class linktree
{
public:
	linknode node;
	binarynode* root;
	int flag;
};
//创建栈中二叉树节点
linktree* creat_linktree_node(binarynode* node,int flag)
{
	linktree* newnode=new linktree;
	newnode->root=node;
	newnode->flag=flag;
	return newnode;
}
//非递归遍历
void nonrecurision(binarynode* root)
{
	//创建栈
	linkstack* stack=init_linkstack();
	//把根节点放入
	push_linkstack(stack,(linknode*)creat_linktree_node(root,my_false));
	while (stack->size>0)
	{
		//弹出栈顶元素
		linktree* node=(linktree*)top_linkstack(stack);
		pop_linkstack(stack);

		//弹出节点判断是否为空
		if (node->root==NULL)
		{
			continue;
		}

		if (node->flag==my_true)
		{
			cout<<node->root->ch<<"\t";
		}
		else  //改变压栈顺序即可改变遍历顺序
		{
			//当前节点左右子树入栈
			push_linkstack(stack,(linknode*)creat_linktree_node(node->root->rchild,my_false)); 
			push_linkstack(stack,(linknode*)creat_linktree_node(node->root->lchild,my_false));
			//当前节点入栈
			node->flag=my_true;
			push_linkstack(stack,(linknode*)node);
		}
	}
	cout<<endl;
}

3、二叉树创建与遍历 

int main()
{
	//创建节点
	binarynode node1={'A',NULL,NULL};
	binarynode node2={'B',NULL,NULL};
	binarynode node3={'C',NULL,NULL};
	binarynode node4={'D',NULL,NULL};
	binarynode node5={'E',NULL,NULL};
	binarynode node6={'F',NULL,NULL};
	binarynode node7={'G',NULL,NULL};
	binarynode node8={'H',NULL,NULL};
	//建立节点关系
	node1.lchild=&node2;
	node1.rchild=&node6;
	node2.rchild=&node3;
	node3.lchild=&node4;
	node3.rchild=&node5;
	node6.rchild=&node7;
	node7.lchild=&node8;
	//非递归先序遍历
	cout<<"非递归先序遍历:"<<endl;
	nonrecurision(&node1);
	system("pause");
	return 0;
}

 

 

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值