采用中序和前序、中序和后序序列创建二叉树 以及对二叉树的前序和后序非递归遍历

类准备

  1. 节点类定义
#include <iostream>
using namespace std;
template<class T>
class BtreeNode{
   public:
   T data;
   BTreeNode<T> * LChild;
   BTreeNode<T> * RChild;
   BtreeNode(T d):data(d){
   LChild = RChild = NULL;
   }
   BtreeNode(){
   LChild = RChild = NULL;
   }
};
  1. 二叉树类定义
template<class T> 
class BinaryTree{
	public :
	BinaryTree(){
	}
	BtreeNode<T> * CreateByPreAndIn(T * a,int s1,int e1,T * b,int s2,int e2);
	BtreeNode<T> * CreateByPostAndIn(T * a,int s1,int e1,T * b,int s2,int e2);
	void PreOrderListWithouRecusion(BtreeNode<T> * root);
	void PostOrderListWithouRecusion(BtreeNode<T> * root);
	~BinaryTree(){
	}
	protected:
	BTreeNode<T> * roots;
};

采用中序和前序、中序和后序序列创建二叉树

  1. 前序和中序创建二叉树
template<T>
BtreeNode<T> * BinaryTree<T>::CreateByPreAndIn(T * a,int s1,int e1,T * b,int s2,int e2){
if(s1>e1)return NULL;
//a == 前序序列  b == 中序序列
BtreeNode<T> * root = new BtreeNode<T>(a[s1]);//前序第一个输出是根
//Find root in b;
int broot = s2;
for(broot;broot <= e2 && b[broot] != a[s1] ;broot++);
//Set Left Tree Length
int leftlength = broot - s2;// 
int rightlength = e2-broot;
//Set Recusion variables
if(leftlength)
root->LChild = CreateByPreAndIn( a, s1+1, s1+leftlength, b,s2, broot - 1);
if(rightlength)
root ->RChild = CreateByPreAndIn( a, s1 + leftlength + 1, e1, b, broot + 1, e2);

//e.g.1 4 3   broot = 4     r->l = ( a,0+1       ,0+4, b, 0      ,4-1)
//	4 1 3			r->r = ( a,0 + 4 + 1,7   , b, 4 + 1,7   )
return root;
}
  1. 后序和中序遍历序列创建
template<T>
BtreeNode<T> * BinaryTree<T>::CreateByPostAndIn(T * a,int s1,int e1,T * b,int s2,int e2){

//a == 后序序列  b == 中序序列
BtreeNode<T> * root = new BtreeNode<T>(a[e1]);//后序最后一个输出是根
//Find root in b;
int broot = s2;
for(broot;broot <= e2 && b[broot] != a[e1] ;broot++);
//Set Left/right ChildTree Length 
int leftlength = broot - s2;
int rightlength = e2-broot;
//Set Recusion variables
if(leftlength)
root->LChild = CreateByPostAndIn( a, s1, s1 + leftlength - 1, b,s2, broot - 1);
if(rightlength)
root ->RChild = CreateByPostAndIn( a, s1 + leftlength , s1 + leftlength + rightlength - 1, b, broot + 1, e2);

//e.g.4 3 1  broot = 4     r->l = ( a,0       ,0 + 4 - 1      , b, 0      ,4-1)
//	4 1 3			r->r = ( a,0 + 4,0 + 4 + 3 - 1, b, 4 + 1,7   )
return root;
}

对二叉树的前序和后序非递归遍历

  1. 非递归前序遍历
include "stack"
template<T>
void * BinaryTree<T>::PreOrderListWithouRecusion(BtreeNode<T> * root){
	if(!root)return;
	stack<BtreeNode<T> *> s;
	BtreeNode<T> * p = root;
	while(p != NULL || !s.isEmpty()){
	if(p){
	//visit p;
	cout<<p->data<<" ";
	if(p->RChild !=NULL)
		s.push(p->RChild);
	//此时栈中是当前存在且未访问的右子树
	p = p->LChild;
	}else{
	/*
	p = s.top();
	s.pop();
	*/
	p = s.pop();
	}
	}
}
  1. 非递归后序遍历
//同上 
//include "stack.h"
template<T>
void * BinaryTree<T>::PostOrderListWithouRecusion(BtreeNode<T> * root){
	if(!root)return;
	stack<BtreeNode<T> *> s;
 	BtreeNode<T> * p = root;
 	BtreeNode<T> * pre= NULL;//记录上一个访问的节点
 	while(p){
		for(;p->LChild != NULL;p = p->LChild)s.push(p);
		//找到“左下角”
		while(p != NULL && (p->RChild == NULL || p->RChild == pre)){
		//当前节点没有右孩子,或者右孩子存在且刚被访问过  那么就轮到访问该节点了
		//visit(p)
		cout<<p->data<<" ";
		pre = p;
		if(s.isEmpty())
			return;
		/*p = s.top();
		s.pop();
		*/
		p = s.pop();
		}
		s.push(p);
		p = p->RChild;
	}
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值