二叉树的实现,使用栈构建一棵二叉树,然后求树高,递归先序遍历,中序遍历,后序遍历,访问左节点,访问右节点,非递归先序遍历输出,非递归中序遍历输出,非递归后序遍历输出。
/*
二叉树实现
*/
#include<iostream>
#include<string>
#include<stack>
#include<fstream>
using namespace std;
const int MAX_N = 100;
//数据节点
class Node
{
public:
char data;//数据
class Node *lchild;//左节点
class Node *rchild;//右节点
};
//二叉树
class Tree
{
public:
Tree(){}
~Tree(){}
//先序遍历非递归算法
void Disp()
{
if (t == NULL)
{
return;
}
stack<Node *> m_stack;
m_stack.push(t);
while (!m_stack.empty())
{
Node *p = m_stack.top();//赋值一份当前双亲节点
cout << p->data << ends;
m_stack.pop();
if (p->rchild)//先存储右子树,确保先输出左子树
{
m_stack.push(p->rchild);
}
if (p->lchild)//后存储左子树
{
m_stack.push(p->lchild);
}
}
}
//非递归中序遍历二叉树
void DispMid()
{
if (t == NULL)
{
return;
}
Node *p = t;
stack<Node *>m_stack;
while (p != NULL || !m_stack.empty())
{
while (p != NULL)//一路直走至左下角
{
m_stack.push(p);
p = p->lchild;
}
if (!m_stack.empty())
{
p = m_stack.top();//备份当前栈顶地址
m_stack.pop();
cout << p->data << ends;
p = p->rchild;
}
}
}
//非递归后序遍历二叉树
void DispBehid()
{
if (t == NULL)
{
return;
}
Node *pre = NULL, *p = t;
stack<Node *>m_stack;
while (p != NULL || !m_stack.empty())
{
while (p != NULL)//一路直走至左下角
{
m_stack.push(p);
p = p->lchild;
}
p = m_stack.top();
//右子树为空或者已访问,输出当前节点
if (p->rchild == NULL || p->rchild == pre)
{
cout << p->data << ends;
pre = p;//将当前结点地址赋值pre作为下一次判断标志,防止重复访问
m_stack.pop();
p = NULL;//p赋值空以便访问右子树
}
else
{
p = p->rchild;//访问子树的右子树
}
}
}
//构建二叉树
void Create(string name)
{
ifstream readfile;
string str;
readfile.open(name);
if (readfile.is_open())
{
getline(readfile, str);//读取一行
}
readfile.close();
CreateNode(str);//构建二叉树
}
//递归先序遍历输出二叉树
void display()
{
cout << "Output:";
output(t);
cout << endl;
}
//递归中序遍历输出二叉树
void displayMid()
{
cout << "Output:";
outputMid(t);
cout << endl;
}
//递归后序遍历输出二叉树
void displayBhind()
{
cout << "output:";
outputBhind(t);
cout << endl;
}
//二叉树高度
void Height()
{
int height = get_height(t);
cout << "Height: " << height << endl;
}
//输出叶子节点值
void display_leaf()
{
cout << "Leaves: ";
output_leaf(t);
cout << endl;
}
private:
Node *t;
//构建二叉树
void CreateNode(string str)
{
stack<Node *> m_stack;
Node *p;
int k;
while (str.length() != 0)
{
//若当前为'(',将双亲节点推入栈,下一位存储的p值作为左节点处理
if (str[0] == '(')
{
m_stack.push(p); k = 1;
}
//为右括号则栈顶退出一位
else if (str[0] == ')')
{
m_stack.pop();
}
//为',',则下一个字符作右节点处理
else if (str[0] == ',')
{
k = 2;
}
//存储值用作双亲结点
else
{
p = (Node *)malloc(sizeof(Node));
p->data = str[0];
p->lchild = p->rchild = NULL;
//树根为空时,将第一个节点作为树根并赋值给私有成员变量
if (t == NULL)
{
t = p;
}
//树根不为空
else
{
if (k == 1)//作为左节点处理,将栈中双亲节点的左指针指向当前节点
{
m_stack.top()->lchild = p;
}
else//作为右节点处理
{
m_stack.top()->rchild = p;
}
}
}
//重构串,除去首字符,并将串长度减小1
str.assign(str.substr(1, str.length() - 1));
}
}
//递归先序遍历输出二叉树
void output(Node *t)
{
if (t != NULL)//当树根不为空时
{
cout << t->data;//输出
if (t->lchild != NULL || t->rchild != NULL)//左/右结点不为空时递归到下一层
{
cout << "(";
output(t->lchild);
if (t->rchild != NULL)//当左节点遍历结束后,左节点递归返回一层,递归右节点
{
cout << ",";
}
output(t->rchild);
cout << ")";
}
}
}
//递归中序遍历二叉树
void outputMid(Node *t)
{
if (t == NULL)
{
return;
}
else
{
cout << "(";
outputMid(t->lchild);
if (t->rchild != NULL)
{
cout << ",";
}
cout << t->data;
outputMid(t->rchild);
cout << ")";
}
}
//递归后序遍历输出二叉树
void outputBhind(Node *t)
{
if (!t)
{
return;
}
else
{
cout << "(";
outputBhind(t->lchild);
if (t->rchild != NULL)
{
cout << ",";
}
outputBhind(t->rchild);
cout << t->data;
cout << ")";
}
}
//求树高
int get_height(Node *t)
{
int leftheight, rightheight;
if (t == NULL)//递归至不存在子节点时返回0
{
return 0;
}
else
{
leftheight = get_height(t->lchild);//递归求左子树高度
rightheight = get_height(t->rchild);//递归其右子树高度
return leftheight > rightheight ? leftheight+1 : rightheight+1;//递归返回时返回最大值
}
}
//查找左节点
Node *leftchild(Node *p)
{
return p->lchild;
}
//查找右节点
Node *rightchild(Node *p)
{
return p->rchild;
}
//输出叶子节点
void output_leaf(Node *t)
{
if (t != NULL)//树根不为空时
{
//当前节点没有子节点时输出节点数据
if (t->lchild == NULL&&t->rchild == NULL)
{
cout << t->data << ends;
}
output_leaf(t->lchild);//递归左子树
output_leaf(t->rchild);//递归右子树
}
}
};
int main()
{
Tree m_tree;
m_tree.Create("data");
m_tree.display();//递归先序输出
m_tree.displayMid();//递归中序输出
m_tree.displayBhind();//递归后序输出
m_tree.Height();//树高
m_tree.display_leaf();//叶子节点
m_tree.Disp();//非递归先序遍历
cout << endl;
m_tree.DispMid();//非递归中序遍历
cout << endl;
m_tree.DispBehid();//非递归后序遍历
cout << endl;
return 0;
}
一次测试结果: