算法学习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;
			}
			
		}
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值