Bootstrap

二叉树的遍历及其应用

#include <iostream>
#include <stack>
using namespace std;

typedef int ElemType;

typedef struct TreeNode *BinTree;
typedef BinTree Position;
typedef struct TreeNode       //二叉树的表示
{
	ElemType Data;
	BinTree Left;
	BinTree Right;
};

//二叉树的几种遍历

//先序遍历
void PreOrderTraversal(BinTree BT)
{
	if (BT)
	{
		cout << BT->Data << " ";
		PreOrderTraversal(BT->Left);
		PreOrderTraversal(BT->Right);
	}
}

//中序遍历
void InOrderTraversal(BinTree BT)
{
	if (BT)
	{
		InOrderTraversal(BT->Left);
		cout << BT->Data << " ";
		InOrderTraversal(BT->Right);
	}
}

//后序遍历
void PostOrderTraversal(BinTree BT)
{
	if (BT)
	{
		PostOrderTraversal(BT->Left);
		PostOrderTraversal(BT->Right);
		cout << BT->Data << " ";
	}
}

//前序遍历非递归算法
void PreOrderTraversal(BinTree BT)
{
	stack<BinTree> S;
	while (BT || !S.empty())
	{
		while (BT)
		{
			S.push(BT);
			cout << BT->Data << " ";
			BT = BT->Left;
		}
		if (!S.empty())
		{
			BT = S.top();
			S.pop();
			BT = BT->Right;
		}
	}
}

//中序遍历非递归算法
void InOrderTraversal(BinTree BT)
{
	stack<BinTree> S;
	while (BT || !S.empty())
	{
		while (BT)
		{
			S.push(BT);
			BT = BT->Left;
		}
		if (!S.empty())
		{
			BT = S.top();
			cout << BT->Data << " ";
			S.pop();
			BT = BT->Right;			
		}
	}
}


//后序遍历非递归算法
void PostOrderTraversal(BinTree BT)
{
	stack<BinTree> S;
	BinTree curr = BT;   //指向当前要检查的节点
	BinTree previsited = NULL; //指向前一个被访问的节点
	
	while (curr != NULL || !S.empty())  //栈为空时结束
	{
		while (curr != NULL) //一直向左走直到空
		{
			S.push(curr);
			curr = curr->Left;
		}
		curr = S.top();
		//当前节点的右孩子如果为空或者已经被访问,则访问当前节点
		if (curr->Right == NULL || curr->Right == previsited)
		{
			cout << curr->Data << " ";
			previsited = curr;
			S.pop();
			curr = NULL;
		}
		else
			curr = curr->Right; //否则访问右孩子
	}
}

//层序遍历二叉树
void LevelOrderTraversal(BinTree BT)
{
	Queue Q;
	if (!BT) return; //若是空树则直接返回
	Q = CreateQueue(MaxSize); //创建并初始化队列Q
	AddQ(Q, BT);
	while (!IsEmptyQ(Q))
	{
		BinTree T = DeleteQ(Q);
		cout << T->Data << endl;  //访问取出队列的结点
		if (T->Left) AddQ(Q, T->Left);
		if (T->Right) AddQ(Q, T->Right);
	}
}

//输出二叉树的叶子结点
void PreOrderPrintLeaves(BinTree BT)
{
	if (BT)
	{
		if (!BT->Left && !BT->Right)
			cout << BT->Data << " ";
		PreOrderTraversal(BT->Left);
		PreOrderTraversal(BT->Right);
	}
}

//求二叉树的高度
int PostOrderGetHeight(BinTree BT)
{
	if (BT)
	{
		int HL = PostOrderGetHeight(BT->Left);
		int HR = PostOrderGetHeight(BT->Right);
		int MaxH = HL > HR ? HL : HR; //左右子树较大的深度
		return MaxH + 1;              //返回树的深度
	}
	else
		return 0;
}


//按照先序构造二叉树
void CreateBinTree(BinTree &root)
{
	char ch;
	cin >> ch;
	if (ch == ' ')
		root = NULL;
	else
	{
		root = new struct TreeNode;
		root->Data = ch;
		CreateBinTree(root->Left);
		CreateBinTree(root->Right);
	}
}

//按照层序生成二叉树算法
BinTree CreateBinTree()
{
	Queue Q = CreateQueue(MaxSize); //生成一个队列
	int data;
	cin >> data; //生成一个队列

	if (data) //分配根结点单元,并将结点地址入队
	{
		BinTree BT = new struct TreeNode;
		BT->Data = data;
		AddQ(Q, BT);
	}
	else return NULL; //若第1个数据就是0,返回空树

	while (!IsEmptyQ(Q))
	{
		BinTree T = DeleteQ(Q); //从队列中取出一结点地址
		cin >> data; //读入T的左孩子
		if (!data)
			T->Left = NULL;
		else          //分配新结点,作为出队结点左孩子,新结点入队
		{
			T->Left = new struct TreeNode;
			T->Left->Data = data;
			AddQ(Q, T->Left);
		}

		cin >> data; //读入T的右孩子
		if (!data)
			T->Right = NULL;
		else          //分配新结点,作为出队结点左孩子,新结点入队
		{
			T->Right = new struct TreeNode;
			T->Right->Data = data;
			AddQ(Q, T->Right);
		}
	}
	return BT;
}

;