二叉树的先序,中序,后序以及层遍历,非递归先序,中序,后序遍历

构建这样一颗二叉树

 

树的结构

class Node
{
public:
	Node() :m_left(NULL), m_right(NULL) {}
	Node(char v) :m_value(v), m_left(NULL), m_right(NULL) {}
	char m_value;
	Node* m_left;
	Node* m_right;
};

二叉树的构建

class Tree
{
public:
	Node* m_root;
	Tree() :m_root(NULL) {}
	Node* CreateTree(const char*& str)
	{
		if (*str == '#')
			return NULL;
		else
		{
			Node* root = new Node(*str);//创建根
			root->m_left = CreateTree(++str);
			root->m_right = CreateTree(++str);
			return root;
		}
	}

	//void Create(Node *&root,const char *&str);
	void PreOrder(Node* t)
	{
		if (t)
		{
			cout << t->m_value << " ";
			PreOrder(t->m_left);
			PreOrder(t->m_right);
		}
	}
	void InOrder(Node* t)//左根右
	{
		if (t)
		{
			InOrder(t->m_left);
			cout << t->m_value << " ";
			InOrder(t->m_right);
		}
	}
	void PostOrder(Node* t)//左右根
	{
		if (t)
		{
			PostOrder(t->m_left);
			PostOrder(t->m_right);
			cout << t->m_value << " ";
		}
	}
	int Size(Node* t)  //以t为根的树的结点个数=左子树+右子树+1(自己)
	{
		if (t == NULL)
			return 0;
		else
			return Size(t->m_left) + Size(t->m_right) + 1;
	}
	int Height(Node* t) //以t为根的树的深度=左子树深度和右子树深度较大值+1
	{
		if (t == NULL)
			return 0;
		else
		{
			int hl = Height(t->m_left);
			int hr = Height(t->m_right);
			return hl > hr ? (hl + 1) : (hr + 1);
		}
	}
	Node* Search(Node* t, char v) //查找值为v的结点,返回指向结点的指针
	{
		if (t == NULL)
			return NULL;
		if (t->m_value == v)
			return t;
		Node* p = Search(t->m_left, v);
		if (p == NULL)
			return Search(t->m_right, v);
	}
	Node* Search_parent(Node* t, char v)
	{
		Node* q = NULL;
		if (t == NULL)
			return NULL;
		if (t->m_left != NULL && t->m_left->m_value == v ||
			t->m_right != NULL && t->m_right->m_value == v)
			return t;
		q = Search_parent(t->m_left, v);
		if (q != NULL)
			return q;
		return Search_parent(t->m_right, v);
	}
	void Copy(Node*& root1, Node*& root2)
	{
		if (root2 == NULL)
			root1 = NULL;
		else
		{
			root1 = new Node(root2->m_value);
			Copy(root1->m_left, root2->m_left);
			Copy(root1->m_right, root2->m_right);
		}
	}
	void LevelOrder(Node* t);
	void PreOrder_1(Node* t); // 先序遍历非递归
	void InOrder_1(Node* t);  //中序遍历非递归
	void PostOrder_1(Node* t); //后序遍历非递归

};

层遍历

void Tree::LevelOrder(Node* t)
{
	queue<Node*> qq;
	Node* front = NULL;
	if (t != NULL)
	{
		qq.push(t); //根入队
		while (!qq.empty()) //如果队列不空
		{
			front = qq.front(); //获取队头,是为了保存下一层的孩子
			qq.pop();
			cout << front->m_value << " ";
			//根据左右顺序将孩子入队
			if (front->m_left != NULL)
				qq.push(front->m_left);
			if (front->m_right != NULL)
				qq.push(front->m_right);
		}
	}
	cout << endl;
}

非递归中序遍历

左根右,访问完最左边孩子,接着要访问它的父节点,所以得保存父节点,自然就能找到右子树
1.先将根以及根下面的所有的左子树全部入栈
2.判断栈是否为空,如果不空,获得栈顶出栈,并用p记住栈顶的右子树
3.查看当前p是否有左子树,如果有,则继续执行1,2,3步骤,直到p为空或者栈为空为止

void Tree::InOrder_1(Node* t)
{
	if (t != NULL)
	{
		stack<Node*>ss;
		Node* p = t;
		Node* top = NULL;
		while (p || !ss.empty())
		{
			while (p != NULL)
			{
				ss.push(p);
				p = p->m_left;
			}
			if (!ss.empty())
			{
				top = ss.top();
				ss.pop();
				cout << top->m_value << " ";
				p = top->m_right; //当前结点遍历完,记住右子树
			}
		}
	}
	cout << endl;
}

非递归先序遍历

1.将根入栈
2.栈不空,获取栈顶并出栈,然后按照右左顺序将当前结点的孩子入栈
  原因:访问左子树,要将右子树保存到栈,为了左子树访问完后访问右子树
3.重复执行2操作,直到栈空为止

void Tree::PreOrder_1(Node* t)
{
	stack<Node*> ss;
	Node* top = NULL;
	if (t != NULL)
	{
		ss.push(t);
		while (!ss.empty())
		{
			top = ss.top();
			ss.pop();
			cout << top->m_value << " ";
			if (top->m_right != NULL)
				ss.push(top->m_right);
			if (top->m_left != NULL)
				ss.push(top->m_left);
		}
	}
	cout << endl;
}

非递归后序遍历

左右根---根右左
注意:需要一个指针记住已经遍历过的结点(出去的结点)
原因:1.入栈:如果当前结点有左右孩子,则按照右左顺序入栈
     出栈:1.如果当前结点没有左右孩子
           2.当前结点有孩子,但是孩子已经遍历过了,则出栈

void Tree::PostOrder_1(Node* t)
{
	if (t != NULL)
	{
		stack<Node*> ss;
		Node* top = NULL, * pre = NULL;
		ss.push(t);
		while (!ss.empty())
		{
			top = ss.top();
			if (top->m_left == NULL && top->m_right == NULL ||
				pre != NULL && top->m_left == pre || pre != NULL && top->m_right == pre)
			{
				ss.pop();
				cout << top->m_value << " ";
				pre = top;
			}
			else
			{
				if (top->m_right != NULL)
					ss.push(top->m_right);
				if (top->m_left != NULL)
					ss.push(top->m_left);
			}
		}
	}
	cout << endl;
}

 主函数

void main()
{
	Tree t;
	Tree t1;
	const char* str = "ABDG##HI####CE#J##F##";
	t.m_root = t.CreateTree(str);
	cout << "先序遍历:";
	t.PreOrder(t.m_root);
	cout << endl;
	cout << "中序遍历:";
	t.InOrder(t.m_root);
	cout << endl;
	cout << "后序遍历:";
	t.PostOrder(t.m_root);
	cout << endl;
	cout << "size = " << t.Size(t.m_root) << endl;
	cout << "Height = " << t.Height(t.m_root) << endl;
	Node* p = t.Search(t.m_root, 'K');
	if (p != NULL)
		cout << "找到了p->value = " << p->m_value << endl;
	else
		cout << "没找到" << endl;
	cout << "copy:" << endl;
	t1.Copy(t1.m_root, t.m_root);
	t1.PreOrder(t1.m_root);
	cout << endl;
	cout << "层次遍历:" << endl;
	t.LevelOrder(t.m_root);
	cout << "非递归先序遍历:" << endl;
	t.PreOrder_1(t.m_root);
	cout << "非递归中序遍历:" << endl;
	t.InOrder_1(t.m_root);
	cout << "非递归后序遍历:" << endl;
	t.PostOrder_1(t.m_root);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值