binTreeNode.h
#pragma once
# include<iostream>
template <typename T>
class binTreeNode
{
public:
binTreeNode() = default;
binTreeNode(const T&t):data(t),lChild(NULL),rChild(NULL)
{}
T data;
binTreeNode *lChild, *rChild;
};
binTree.h
#pragma once
# include"binTreeNode.h"
#include<iostream>
# include<string>
# include"myQuene.h"
# include"myStack.h"
using namespace std;
template <typename T>
class binTree
{
public:
//构造函数:建立二叉树,元素为#时表示为该节点为空
binTree() = default;
~binTree();//析构函数
binTree(const binTree&t);
void levelCreate();//按层次建立二叉树
void visit(binTreeNode<T> *node);//访问节点
void inTraver(binTreeNode<T> *p);//中序遍历
void prevTraver(binTreeNode<T> *p);//先序遍历
void postTraver(binTreeNode<T> *p);//后序遍历
void inTraver1();//中序遍历(非递归)
void prevTraver1();//先序遍历(非递归)
void postTraver1();//后序遍历(非递归)
void levelTraver();//层次遍历
int countOfNode(binTreeNode<T> *);//树的节点个数
int height(binTreeNode<T> *); //树的高度
binTreeNode<T>* &getRoot() { return root; }//返回根节点
void destroy(binTreeNode<T> *);
private:
binTreeNode<T> *root;//二叉树的根节点
};
template<typename T>
binTree<T>::~binTree()
{
if (root)
delete root;
}
template<typename T>
void binTree<T>::levelCreate()//按层次建立树
{
T elem;
int i = 1;//i表示正在处理的节点的序号,初始化为处理第一个节点
binTreeNode<T>** (arr[100]) = {};
/*
保存指向每个节点的指针,比如建立下面这样的树(括号左边是序号,括号里面节点元素,以整型为例,输入
0表示为空节点):
1(1)
2(2) 3(3)
4(0) 5(4) 6(5) 7(6)
输入时应输入:1 2 3 0 4 5 6
比如处理节点元素为4时,要改变其双亲节点,对吧,令其双亲的rChild指针指向正在处理的节点,所以
我就定义一个数组保存指针,可能空间开销比较大
*/
while (cin >> elem)
{
if (i == 1)//第一个元素,处理根节点
{
arr[i - 1] = &root;
root = new binTreeNode<T>(elem);
i++;
continue;
}
if (elem == 0||elem=='0')//如果是空节点
{
if (i % 2 == 0&&(arr[i/2-1]))//能够被2整除,那么该节点为其双亲的左孩子,并且其双亲
//应该存在,才可以令其双亲的左孩子指针为空
((*arr[i / 2-1]))->lChild = NULL;
else if(arr[i/2-1])//否咋是其右孩子
((*arr[i / 2-1]))->rChild = NULL;
arr[i - 1] = NULL;//此节点为空
i++;
continue;
}
arr[i - 1] = new binTreeNode<T> *;//节点不位空
binTreeNode<T> *temp = new binTreeNode<T>(elem);
if (i % 2 == 0)
(*arr[i / 2-1])->lChild = temp;//同理
else (*arr[i / 2-1])->rChild = temp;
*arr[i - 1] = temp;//保存节点指针
i++;
}
}
template <typename T>
void binTree<T>::visit(binTreeNode<T> *node)//访问元素
{
cout << node->data<<" ";
}
template <typename T>
void binTree<T>::inTraver(binTreeNode<T> *p)//中序遍历
{
if (p)
{
inTraver(p->lChild);
visit(p);
inTraver(p->rChild);
}
}
template <typename T>
void binTree<T>::prevTraver(binTreeNode<T> *p)//先序遍历
{
if (p)
{
visit(p);
prevTraver(p->lChild);
prevTraver(p->rChild);
}
}
template <typename T>
void binTree<T>::postTraver(binTreeNode<T> *p)//后序遍历
{
if (p)
{
postTraver(p->lChild);
postTraver(p->rChild);
visit(p);
}
}
template<typename T>
void binTree<T>::inTraver1()//中序遍历(非递归)
{
myStack<binTreeNode<T> *> s;
binTreeNode<T> *t=root;
while (t || !s.empty())//当t不为空或s不为空时
{
if (t)//如果t不为空
{
s.push(t);//保留t
t = t->lChild;
}
else
{
s.pop(t);
visit(t);
t = t->rChild;
}
}
}
template<typename T>
void binTree<T>::prevTraver1()//先序遍历(非递归)
{
myStack<binTreeNode<T> *> s;
binTreeNode<T>* t=root;
while (t || !s.empty())
{
if (t)
{
visit(t);
s.push(t);
t = t->lChild;
}
else
{
s.pop(t);
t = t->rChild;
}
}
}
template<typename T>
void binTree<T>::postTraver1()//后序遍历(非递归)
{
myStack<binTreeNode<T> *> s;
myStack<T> s1;
binTreeNode<T>* t = root;
while (t || !s.empty())
{
if (t)
{
s1.push(t->data);
s.push(t);
t = t->rChild;
}
else
{
s.pop(t);
t = t->lChild;
}
}
T temp;
while (!s1.empty())
{
s1.pop(temp);
cout << temp << " ";
}
}
template <typename T>
void binTree<T>::levelTraver()
{
myQuene<binTreeNode<T> *> q(30);
binTreeNode<T> *t;
if (root)
{
visit(root);
q.in(root);
}
while (!q.empty())
{
q.out(t);
if (t->lChild)
{
visit(t->lChild);
q.in(t->lChild);
}
if (t->rChild)
{
visit(t->rChild);
q.in(t->rChild);
}
}
}
template<typename T>
int binTree<T>::countOfNode(binTreeNode<T> *n)
{
//int count = 0;
if (n)
{
countOfNode(n->lChild);
return countOfNode(n->lChild)+countOfNode(n->rChild)+1;
}
else return 0;
}
template<typename T>
int binTree<T>::height(binTreeNode<T> *n) //树的高度
{
if (n)
{
int h1 = height(n->lChild);
int h2 = height(n->rChild);
if (h1 > h2)
return h1 + 1;
return h2 + 1;
}
return 0;
}
template<typename T>
void binTree<T>::destroy(binTreeNode<T> *n)
{
binTreeNode<T> *l,*r;
if (n)
{
l = n->lChild;
r = n->rChild;
delete n;
destroy(l);
destroy(r);
}
root = NULL;
}
main.cpp
# include"BinTree.h"
# include<iostream>
using namespace std;
int main()
{
binTree<char> myBinTree;
cout << "建立二叉树,元素为0时表示为该节点为空(元素为int型):" << endl;
myBinTree.levelCreate();
auto &p = myBinTree.getRoot();
cout << endl << "先序遍历为:";
myBinTree.prevTraver(p);
cout <<endl<<"中序遍历为:" ;
myBinTree.inTraver(p);
cout << endl << "后序遍历为:";
myBinTree.postTraver(p);
cout << endl << "层次遍历为:";
myBinTree.levelTraver();
cout <<endl<<endl<< "树的节点个数为:" << myBinTree.countOfNode(p) << endl;
cout << "树的高度为:" << myBinTree.height(p) << endl;
cout << endl << "先序非递归遍历:";
myBinTree.prevTraver1();
cout <<endl<< "中序非递归遍历:";
myBinTree.inTraver1();
cout << endl << "后序非递归遍历:";
myBinTree.postTraver1();
cout <<endl<< "销毁二叉树后:" << endl;
myBinTree.destroy(p);
myBinTree.levelTraver();
/*cout << endl;
cout << endl<<endl;*/
return 0;
}