利用栈结构实现二叉树的非递归遍历,求二叉树深度、叶子节点数、两个结点的最近公共祖先及二叉树结点的最大距离

利用栈实现二叉树的非递归遍历,并求二叉树的深度、叶子节点数、两个节点的最近公共祖先以及二叉树结点的最大距离,部分参考《剑指offer》这本书,其代码如下:

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

typedef struct BiNode //定义一棵二叉树
{
	char val;
	struct BiNode *left;
	struct BiNode *right;
	BiNode(char x) :val(x), left(NULL), right(NULL){}
}BiNode,*BiTree;

void CreateBiTree(BiTree &T)//前序创建一颗二叉树
{
	char c;
	cin >> c;
	if ('#' == c)
		T=NULL;
	else
	{
		T = (BiNode* ) malloc(sizeof(BiNode));
		T->val = c;
		CreateBiTree(T->left);
		CreateBiTree(T->right);
	}
}

//二叉树的非递归遍历(前序、中序、后序及层序)
void PreOrder(BiTree& T)//前序遍历,非递归
{
	if (T == NULL)
		return;
	vector<BiNode*> S;
	BiNode *p = T;
	while (p != NULL || !S.empty())
	{
		while (p != NULL)
		{
			cout << p->val << " ";
			S.push_back(p);
			p = p->left;
		}
		if (!S.empty())
		{
			p = S[S.size() - 1];
			S.pop_back();
			p = p->right;
		}
	}
	cout << endl;
}

void InOrder(BiTree& T)//中序遍历,非递归
{
	if (T == NULL)
		return;
	vector<BiNode*> S;
	BiNode *p = T;
	while ( p != NULL || !S.empty())
	{
		while (p != NULL)
		{
			S.push_back(p);
			p = p->left;
		}
		if (!S.empty())
		{
			p = S[S.size() - 1];
			cout << p->val << " ";
			S.pop_back();
			p = p->right;
		}
	}
	cout << endl;
}

void PostOrder(BiTree &T)//后序遍历(双栈法),非递归
{
	if (T == NULL)
		return;
	vector<BiNode*> S1,S2;
	BiNode *p ;//当前指针所在结点
	S1.push_back(T);
	while (!S1.empty())
	{
		p = S1[S1.size() - 1];
		S1.pop_back();
		S2.push_back(p);
		if (p->left)
			S1.push_back(p->left);
		if (p->right)
			S1.push_back(p->right);
	}
	while (!S2.empty())
	{
		cout << S2[S2.size() - 1]->val << " ";
		S2.pop_back();
	}
	cout << endl;
}

void LevelOrder(BiTree &T)//非递归层序遍历,可选择按层输出结点,也可用于计算二叉树的深度
{
	if (T == NULL)
		return;
	vector<BiNode*> S;
	S.push_back(T);
	//int depth = 0;//统计二叉树的深度
	int cur = 0;
	int last = 1;
	while (cur < S.size())
	{
		last = S.size();
		while (cur < last)
		{
			cout << S[cur]->val << " ";
			if (S[cur]->left != NULL)
				S.push_back(S[cur]->left);
			if (S[cur]->right != NULL)
				S.push_back(S[cur]->right);
			++cur;
		}
		//cout << endl;如果需要按层输出每一层的结点则取消此行注释
		//depth++;//如果要求二叉树的深度,只需在此统计输出了多少次endl就可以
	}
	cout << endl;
}

void LevelOrder2(BiTree &T)//层序遍历,非递归(双栈法),奇偶层数存储有区别时可实现之字形打印
{
	if (T == NULL)
		return;
	stack<BiNode*> Levels[2];
	int cur = 0;//奇数行
	int next = 1;//偶数行
	Levels[cur].push(T);
	while (!Levels[0].empty() || !Levels[1].empty())
	{
		BiNode *p = Levels[cur].top();
		Levels[cur].pop();
		cout << p->val << " ";
		if (cur == 0)//奇数层顺序存储
		{
			if (p->left != NULL)
				Levels[next].push(p->left);
			if (p->right != NULL)
				Levels[next].push(p->right);
		}
		else//偶数层逆序存储
		{
			if (p->right != NULL)
				Levels[next].push(p->right);
			if (p->left != NULL)
				Levels[next].push(p->left);
		}
		if (Levels[cur].empty())
		{
			//cout << endl;//换行,如果不换行可以注释掉这条
			cur = 1 - cur;
			next = 1 - next;
		}
	}
	cout << endl;
}

void GetNodePath(BiNode* T, BiNode* Node, vector<BiNode*>& Path,int &found)//获取二叉树中从根节点到指定节点的路径 
{
	if (T == NULL)
		return;
	Path.push_back(T);
	if (T == Node)
		found = 1;
	if (!found)
	{
		GetNodePath(T->left, Node, Path, found);
	}
	if (!found)
	{
		GetNodePath(T->right, Node, Path, found);
	}
	if (!found)
		Path.pop_back();
	else
		return;
}
BiNode* GetLastCommonNode(const vector<BiNode*> Path1, const vector<BiNode*> Path2)//获取两条路径的最后一个共同节点
{
	vector<BiNode*>::const_iterator iter1 = Path1.begin();
	vector<BiNode*>::const_iterator iter2 = Path2.begin();
	BiNode *p = NULL;
	while (iter1 != Path1.end() && iter2 != Path2.end())
	{
		if (*iter1 == *iter2)
			p = *iter1;
		iter1++;
		iter2++;
	}
	return p;
}
BiNode* GetLastCommonParent(BiNode* T, BiNode* Node1, BiNode* Node2)//获取两个结点的最近共同祖先
{
	if (T == NULL || Node1 == NULL || Node2 == NULL)
		return NULL;
	vector<BiNode*> Path1, Path2;
	int found1 = 0;
	int found2 = 0;
	GetNodePath(T, Node1, Path1,found1);
	GetNodePath(T, Node2, Path2, found2);
	return GetLastCommonNode(Path1,Path2);
}

int GetTreeDepth(BiTree &T)//计算二叉树的深度,递归法
{
	if (T == NULL)
		return 0;
	int Dleft = GetTreeDepth(T->left);
	int Dright = GetTreeDepth(T->right);
	return (Dleft > Dright) ? (Dleft + 1) : (Dright + 1);
}

int CountLeafNode(BiTree &T)//计算二叉树的叶子节点数目,递归法
{
	if (T == NULL)
		return 0;
	if (T->left == NULL&&T->right == NULL)
		return 1;
	return CountLeafNode(T->left)+CountLeafNode(T->right);
}

int GetMaxDistance(BiTree &T)//计算二叉树结点的最大距离,递归法
{
	if (T == NULL)
		return 0;
	int Distance = GetTreeDepth(T->left) + GetTreeDepth(T->right);
	int l_Distance = GetMaxDistance(T->left);
	int r_Distance = GetMaxDistance(T->right);
	Distance = (Distance > r_Distance) ? Distance : r_Distance;
	Distance = (Distance > l_Distance) ? Distance : l_Distance;
	return Distance;
}

int main()
{
	//BiTree T;
	//cout << "前序创建一颗二叉树T,请输入节点:" << endl;
	//CreateBiTree(T);
	//cout << endl;
	//*******************另一种方式创建二叉树T************************************************************
	BiNode Node1('1'), Node2('2'), Node3('3'), Node4('4'), Node5('5'), Node6('6'), Node7('7'), Node8('8');
	Node1.left = &Node2;
	Node1.right = &Node3;
	Node2.left = &Node4;
	Node3.left = &Node5;
	Node3.right = &Node6;
	Node4.right = &Node7;
	Node5.right = &Node8;
	BiNode* T = &Node1;
	BiNode* P1 = &Node7;
	BiNode* P2 = &Node8;
	//****************************************************************************************************
	cout << "前序遍历结果: ";
	PreOrder(T);
	cout << endl;
	cout << "中序遍历结果: ";
	InOrder(T);
	cout << endl;
	cout << "后序遍历结果: ";
	PostOrder(T);
	cout << endl;
	cout << "层序遍历结果: ";
	LevelOrder(T);
	cout << endl;
	cout << "层序之字形遍历结果: ";
	LevelOrder2(T);
	cout << endl;
	cout << "结点7和8的最近公共祖先是: "<<GetLastCommonParent(Root, P1, P2)->val << endl;
	cout << endl;
	cout << "二叉树的深度: "<<GetTreeDepth(T)<< endl;
	cout<<endl;
	cout << "二叉树的叶子节点个数:"<<CountLeafNode(T)<< endl;
	cout << endl;
	cout << "二叉树结点的最大距离: " << GetMaxDistance(T) << endl;
	cout << endl;
	system("pause");
	return 0;
}   

实验输入的二叉树结构如下:

                                          1

                                       /       \

                                    2           3

                                 /              /    \

                              4              5       6

                               \                 \

                                7                8

实验结果如下所示:

利用栈结构实现二叉树的非递归遍历,求二叉树深度、叶子节点数、两个结点的最近公共祖先及二叉树结点的最大距离_第1张图片

你可能感兴趣的:(C++,二叉树,遍历,栈,非递归)