参考链接:http://blog.csdn.net/j_anson/article/details/49671523
二叉树的实现,使用栈构建一棵二叉树,然后求树高,递归先序遍历,中序遍历,后序遍历,访问左节点,访问右节点,非递归先序遍历输出,非递归中序遍历输出,非递归后序遍历输出。
- /*
- 二叉树实现
- */
- #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;
- }
一次测试结果: