二叉树的结点定义及类定义:BinaryTree.h
因为用的是模板类,.h和.cpp文件不能分开,类定义和函数实现就全写在.h里了
主要是二叉树的前、中、后序的递归与非递归周游
#ifndef BINARYTREE_H_INCLUDED
#define BINARYTREE_H_INCLUDED
#include
#include
#include
#include
using namespace std;
template
class BinaryTree;
template
class BinaryTreeNode{
friend class BinaryTree;
private:
T element; //结点的数据域
BinaryTreeNode *leftChild; //结点的左孩子结点
BinaryTreeNode *rightChild; //结点的右孩子结点
public:
BinaryTreeNode(){ //默认构造函数
leftChild = NULL;
rightChild = NULL;
}
//给定数据值和左右孩子结点的构造函数
BinaryTreeNode(const T& ele, BinaryTreeNode *l = NULL, BinaryTreeNode *r = NULL){
element = ele;
leftChild = l;
rightChild = r;
}
BinaryTreeNode* getLeftChild() const{ //返回该结点的左孩子结点
return leftChild;
}
BinaryTreeNode* getRightChild() const{ //返回该结点的右孩子结点
return rightChild;
}
void setLeftChild(BinaryTreeNode *l){ //设置该结点的左孩子结点
leftChild = l;
}
void setRightChild(BinaryTreeNode *r){ //设置该结点的右孩子结点
rightChild = r;
}
T getValue() const{ //返回该结点的数据值
return element;
}
void setValue(const T& val){ //设置该结点的数据值
element = val;
}
bool isLeaf() const{ //判断该结点是否为叶子结点
return (!leftChild && !rightChild);
}
};
template
class BinaryTree{
private:
BinaryTreeNode *root; //二叉树根节点
public:
BinaryTree(){ //默认构造函数
root = NULL;
}
~BinaryTree(){ //析构函数
destory(root);
}
BinaryTreeNode* creatTree(vector a, int size, int &i, T& invalid){ //创建二叉树
BinaryTreeNode* _root = NULL;
if(i < size && a[i] != invalid){
_root = new BinaryTreeNode();
_root->setValue(a[i]);
if(i == 0)
root = _root;
_root->setLeftChild(creatTree(a, size, ++i, invalid));
_root->setRightChild(creatTree(a, size, ++i, invalid));
}
return _root;
}
void destory(BinaryTreeNode* node){ //销毁二叉树
BinaryTreeNode* temp = node;
if(temp == NULL)
return;
destory(temp->leftChild);
destory(temp->rightChild);
delete temp;
temp = NULL;
}
bool isEmpty() const{ //判断二叉树是否为空树
return (root == NULL);
}
BinaryTreeNode* getRoot() const{ //返回二叉树的根结点
return root;
}
void setRoot(BinaryTreeNode *node){
root = node;
}
BinaryTreeNode* getParent(BinaryTreeNode* current) const{ //返回current结点的父结点
}
BinaryTreeNode* getLeftSibling(BinaryTreeNode* current) const{ //返回current结点的左兄弟
return current->leftChild;
}
BinaryTreeNode* getRightSibling(BinaryTreeNode* current) const{ //返回current结点的右兄弟
return current->rightChild;
}
void breadthFirstOrder(){ //广度优先遍历以riit为根结点的子树
queue *> nodeQueue;
BinaryTreeNode *pointer = root;
if(pointer)
nodeQueue.push(pointer);
while(!nodeQueue.empty()){
pointer = nodeQueue.front();
visit(pointer);
nodeQueue.pop();
if(pointer->leftChild)
nodeQueue.push(pointer->leftChild);
if(pointer->rightChild)
nodeQueue.push(pointer->rightChild);
}
cout<* node){ //前序递归遍历二叉树或其子树
BinaryTreeNode* pointer = node;
if (pointer != NULL) {
visit(pointer); // 访问当前结点
PreOrder(pointer->leftChild); // 前序遍历左子树
PreOrder(pointer->rightChild); // 前序遍历右子树
}
}
void MidOrder (BinaryTreeNode* node){ //中序递归遍历二叉树或其子树
BinaryTreeNode* pointer = node;
if (pointer != NULL) {
MidOrder(pointer->leftChild);
visit(pointer);
MidOrder(pointer->rightChild);
}
}
void AftOrder (BinaryTreeNode* node){ //后序递归遍历二叉树或其子树
BinaryTreeNode* pointer = node;
if (pointer != NULL) {
AftOrder(pointer->leftChild);
AftOrder(pointer->rightChild);
visit(pointer);
}
}
void visit(BinaryTreeNode* current){ //访问当前结点
cout<element<<'\t';
}
void preTraversal(BinaryTreeNode *root){ //深度前序非递归周游
stack*> s;
BinaryTreeNode* pointer = root;
while(!s.empty() || pointer){ //栈空且指针指向NULL时停止循环
if(pointer){
visit(pointer);
if(pointer->rightChild != NULL) //非空右孩子入栈
s.push(pointer->rightChild);
pointer = pointer->leftChild;
}else{
pointer = s.top(); //获得栈顶元素
s.pop(); //弹栈
}
}
}
void midTraversal(BinaryTreeNode *root){ //深度中序非递归周游
stack*> s;
BinaryTreeNode *pointer = root;
while(!s.empty() || pointer){
if(pointer){
s.push(pointer); //当前指针入栈
pointer = pointer->leftChild; //左路下降
}else{ //左子树访问完毕,转向访问右子树
pointer = s.top(); //获得栈顶元素
s.pop(); //弹栈
visit(pointer); //访问当前结点
pointer = pointer->rightChild; //指针指向右孩子
}
}
}
void aftTraversal(BinaryTreeNode *root){ //深度后序非递归周游
stack*> s;
BinaryTreeNode *p = root, //当前指针
*q = root; //上一个访问的指针
while(p != NULL){
for(; p->leftChild != NULL; p = p->leftChild) //从左下第一个结点开始循环
s.push(p);
while(p != NULL && (p->rightChild == NULL || p->rightChild == q)){ //当前结点不为空并且其右孩子为空或访问过则访问当前结点
visit(p);
q = p;
if(s.empty()) //栈空则返回
return;
p = s.top(); //弹栈
s.pop();
}
s.push(p); //当前结点不为空且右孩子没被访问过则当前结点入栈
p = p->rightChild;
}
}
};
#endif // BINARYTREE_H_INCLUDED
#ifndef RELATEDFUN_H_INCLUDED
#define RELATEDFUN_H_INCLUDED
#include
#include "BinaryTree.h"
extern void createTree(string s1, string s2, string type);
#endif // RELATEDFUN_H_INCLUDED
relatedFun.cpp
#include "relatedFun.h"
void preMidCreate(string pre, string mid, BinaryTreeNode *node){ //已知前序中序生成树
int ssize = pre.size();
node->setValue(pre[0]); //设定当前结点值为前序字符串第一个字符
if(ssize == 1) //字符串长度为1时停止递归
return;
else{
for(int i = 0; i < ssize; i ++){
if(mid[i] == pre[0]){ //中序字符等于前序第一个字符时
if(i != 0){ //如果不在中序字符串首,则有左孩子
BinaryTreeNode *left;
left = new BinaryTreeNode(); //创建新结点
node->setLeftChild(left);
string p (pre.substr(1, i)); //以当前字符为界分割字符串
string m (mid.substr(0, i));
preMidCreate(p, m, left); //递归调用
}
if(i != ssize - 1){ //如果不在中序字符串尾,则有右孩子
BinaryTreeNode *right;
right = new BinaryTreeNode();
node->setRightChild(right);
string p (pre.substr(i + 1));
string m (mid.substr(i + 1));
preMidCreate(p, m, right);
}
}
}
}
}
void midAftCreate(string mid, string aft, BinaryTreeNode *node){ //已知中序后序生成树
int ssize = mid.size();
node->setValue(aft[ssize - 1]); //当前字符为后序字符串最后一个字符
if(ssize == 1)
return;
else{
for(int i = 0; i < ssize; i ++){
if(mid[i] == aft[ssize - 1]){
if(i != 0){
BinaryTreeNode *left;
left = new BinaryTreeNode();
node->setLeftChild(left);
string a (aft.substr(0, i));
string m (mid.substr(0, i));
midAftCreate(m, a, left);
}
if(i != ssize - 1){
BinaryTreeNode *right;
right = new BinaryTreeNode();
node->setRightChild(right);
string a (aft.substr(i, ssize-1));
string m (mid.substr(i + 1));
midAftCreate(m, a, right);
}
}
}
}
}
void createTree(string s1, string s2, string type){
BinaryTree tree;
BinaryTreeNode *node = new BinaryTreeNode();
tree.setRoot(node);
if(type == "premid")
preMidCreate(s1, s2, node);
else if(type == "midaft")
midAftCreate(s1, s2, node);
tree.preTraversal(tree.getRoot()); //前序周游二叉树
cout<
主函数测试:main.cpp
#include "relatedFun.h"
#include "BinaryTree.h"
#include"stdio.h"
int main()
{
string pre;
string mid;
string aft;
cout<<"请输入先序序列:"<>pre;
cout<<"请输入中序序列:"<>mid;
cout<<"请输入后序序列:"<>aft;
createTree(pre, mid, "premid");
createTree(mid, aft, "midaft");
return 0;
}