二叉树的实现(递归遍历和非递归遍历)C++

二叉树的实现,使用栈构建一棵二叉树,然后求树高,递归先序遍历,中序遍历,后序遍历,访问左节点,访问右节点,非递归先序遍历输出,非递归中序遍历输出,非递归后序遍历输出。

/*
二叉树实现
*/
#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;
}

一次测试结果:



  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值