算法学习13:分别用递归和非递归方式实现二叉树先序、中序和后序遍历

数据结构

树结点

class Tree{
	public:
		int data;
		Tree* left;
		Tree* right;
		Tree(int x){this->data=x;left=NULL;right=NULL;}
};

构造一颗二叉树

Tree* head=new Tree(1);
head->left=new Tree(2);
head->right=new Tree(3);
head->left->left=new Tree(4);
head->left->right=new Tree(5);
head->right->left=new Tree(6);
head->right->right=new Tree(7);

二叉树遍历递归版

在二叉树的递归遍历中,每个节点都会被访问三次(第一次回到达某个节点,第二次为遍历完该节点的左数后返回,第三次为遍历完这个节点的右树返回)下面代码注释部分的123代表第123次到达该节点的时候。

public f(Tree* head){
//1
	if(head!=NULL){
		return;
	}
	//1
	f(head->left);
	//2
	//2
	f(head->right);
	//3
	//3
}

先序遍历就是先打印头结点的信息,再打印左节点和右节点。根据递归序加工就可以得到想要的访问次序。在第一次到达节点后,就打印信息。二三次时候不进行操作。
中序遍历就是先打印左树再打印头最后打印右树。利用递归序,第二次来到某个节点才打印,不是第二次不打印。
后序遍历就是先左树再右树最后头,递归序中第三次访问就是后序。
先序

void preOrderRecur (Tree* head){
	if(head!=NULL){
		return;
	}
	cout<<head->data;
	preOrderRecur(head->left);
	preOrderRecur(head->right);
}

中序和后序的代码同理省略。

非递归方法实现二叉树先序遍历

  1. 申请一个新栈,记为stack。然后将头结点head压入栈stack中。
  2. 从stack中弹出栈顶节点,记为cur,打印cur的值。再将cur的右节点压入栈中,再将cur的左节点压入栈中。
  3. 不断重复步骤2,直到stack为空,全部过程结束。
void preOrderRecur (Tree* head){
	stack<Tree*> t;
	t.push(head);
	while(!t.empty()){
		head=t.top();
		cout<<t.top()->data;
		t.pop();
		if(head->right!=NULL){
			t.push(head->right);
			}
		if(head->left!=NULL){
			t.push(head->left);
			}
	}
}

非递归实现二叉树后序遍历

分析:先序遍历的访问顺序是头左右,如果在压入堆栈的过程先压左再压右,那么此时的访问顺序就变为头右左,如果将要访问的数据推入一个新的栈中,就可以实现逆序访问,即左右头。

void preOrderUnRecur(Tree* head){
	stack<int> t;
	stack<int> t1;
	if(head!=NULL){
		t1.push(head);
	}
	while(!t.empty()){
		head=t.pop();
		t1.push(head);
		if(head->left!=NULL){
			t.push(head->left);
	}
		if(head->right!=NULL){
			t.push(head->right);
		}
	}
	while(!t1.empty()){
		cout<<t1.pop();
	}


}

非递归实现二叉树中序遍历

先将整颗树的左边界压入栈中,依次弹出的过程中打印,对弹出节点的右树的左边界压入栈中。

void inOrderUnRecur(Tree* head){
	if(head!=NULL){
		stack<int>s;
		s.push(head);
		while(!s.empty()||head!=NULL){
			if(head!=NULL){
				t.push(head);
				head=head->left;
			}else{
				head=t.pop();
				cout<<head->data;
				head=head->right;
			}
			
		}
	}
}
  • 0
    点赞
  • 2
    收藏
  • 打赏
    打赏
  • 1
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:技术工厂 设计师:CSDN官方博客 返回首页
评论 1

打赏作者

为成大道踏平坎坷

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值