类准备
- 节点类定义
#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;
}
};
- 二叉树类定义
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;
};
采用中序和前序、中序和后序序列创建二叉树
- 前序和中序创建二叉树
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;
}
- 后序和中序遍历序列创建
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;
}
对二叉树的前序和后序非递归遍历
- 非递归前序遍历
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();
}
}
}
- 非递归后序遍历
//同上
//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;
}
}