二叉树系列问题1

1、非递归实现二叉树的三种遍历

2、分层遍历二叉树

3、找出二叉树上任意两个节点的共同父节点

4、找出二叉树中和为某值的所有路径

5、二叉树的镜像

首先是树节点和树的类数据结构

#define ElementType int

class BinTree;
class BinTreeNode
{
public:
	friend class BinTree;
	
	BinTreeNode():Left(NULL),Right(NULL){}
	BinTreeNode(ElementType temp, BinTreeNode * pLeft = NULL, BinTreeNode * pRight = NULL):data(temp), Left(pLeft), Right(pRight){}
	ElementType GetData() const;
	BinTreeNode * GetLeft() const;
	BinTreeNode *GetRight()const;

	void SetData(const ElementType temp);
	void SetLeft(BinTreeNode *pLeft);
	void SetRight(BinTreeNode *pRight);

	void InOrder();
	void PreOrder();
	void PostOrder();

	int Size();
	int Height();

	bool isAvlTree();//该节点是不是平衡的
	BinTreeNode *Copy(const BinTreeNode *copy);
	void Destroy();

	friend bool Equal(const BinTreeNode *s, const BinTreeNode *t);
private:
	BinTreeNode *Left, *Right;
	ElementType data;
};

class BinTree
{
public:
	BinTree():Root(NULL){}
	BinTree(const BinTree & temp);
	virtual ~BinTree()
	{
		Root->Destroy();
	}
	virtual bool IsEmpty();
	virtual BinTreeNode* GetLeft(BinTreeNode *current);
	virtual BinTreeNode* GetRight(BinTreeNode *current);
	virtual BinTreeNode* GetParent(BinTreeNode *current);
	const BinTreeNode* GetRoot()const;
	BinTreeNode* GetRoot();
	virtual bool Insert(const ElementType temp);
	virtual BinTreeNode *Find(const ElementType temp)const;

	void InOrder();
	void PreOrder();
	void PostOrder();
	void InOrderWithCycle();//循环实现树的三种遍历
	void PreOrderWithCycle();
	void PostOrderWithCycle();

	int Size();
	int Height();
	bool isAvlTree(); //判断一课数是不是平衡二叉树

	BinTree& operator=(const BinTree copy);
	friend bool operator == (const BinTree s, const BinTree t);
	friend ostream& operator<<(ostream& os, BinTree& temp);
	friend istream& operator>>(istream& is, BinTree& temp);
private:
	BinTreeNode *Root;
	BinTreeNode * GetParent(BinTreeNode *start, BinTreeNode *current);
	BinTreeNode *Insert(BinTreeNode *, ElementType temp);
	void Print(BinTreeNode *start, int n = 0);
};
1、非递归实现二叉树的三种遍历

void BinTree::InOrderWithCycle()//中
{
	stack<BinTreeNode *> s;
	BinTreeNode *pMove;
	pMove = this->Root;
	while(pMove != NULL || !s.empty())
	{
		while(pMove != NULL)
		{
			s.push(pMove);
			pMove = pMove->Left;
		}
		if(!s.empty())
		{
			pMove = s.top();
			s.pop();
			cout<<pMove->data<<" "<<endl;
			pMove = pMove->Right;
		}
	}
}
void BinTree::PreOrderWithCycle()//前
{
	stack<BinTreeNode *> s;
	BinTreeNode *pMove;
	pMove = this->Root;
	while(pMove != NULL || !s.empty())
	{
		while(pMove != NULL)
		{
			cout<<pMove->data <<" "<<endl;
			s.push(pMove);
			pMove = pMove->Left;
		}
		if(!s.empty())
		{
			pMove = s.top();
			s.pop();
			pMove = pMove->Right;
		}
	}
}

void BinTree::PostOrderWithCycle()//后
{
	stack<BinTreeNode *> s;
	BinTreeNode *pMove;
	BinTreeNode *pre = NULL;
	pMove = this->Root;
	s.push(pMove);
	while(!s.empty())
	{
		pMove = s.top();
		if((pMove->Left == NULL && pMove->Right == NULL) || (pre != NULL && (pMove->Left == pre || pMove->Right == pre)))//判断节点是否是叶子节点,或者该节点的左右子树是否已经遍历过
		{
			//pMove = s.top();
			cout<<pMove->data<<" "<<endl;
			pre = pMove;
			s.pop();
		}
		else
		{
			if(pMove->Right)
				s.push(pMove->Right);
			if(pMove->Left)
				s.push(pMove->Left);
		}
	}
}
2、分层遍历二叉树

把节点入栈,然后左右节点入栈

void PrintTreeInlayer(BinTree &Tree)//分层遍历二叉树
{
	queue<const BinTreeNode *> q;
	if(Tree.IsEmpty())
		return;
	const BinTreeNode *temp;
	q.push(Tree.GetRoot());
	while(!q.empty())
	{
		temp = q.front();
		cout<<temp->GetData()<<" "<<endl;
		q.pop();
		if(temp->GetLeft())
			q.push(temp->GetLeft());
		if(temp->GetRight())
			q.push(temp->GetRight());
	}

}

3、找出二叉树上任意两个节点的最近共同父节点

分别遍历两个节点,并把经过的节点方入容器,然后从头遍历两个容器,最后一个相同的节点就是最近的共同父节点

const BinTreeNode *FindPublicNode(ElementType first, ElementType second,const BinTreeNode *Root)//二叉树的最近公共父节点
{
	void FindPath(vector<const BinTreeNode *>&, ElementType ,const BinTreeNode *);
	vector<const BinTreeNode *>FirstVec, SecondVec;
	FindPath(FirstVec, first, Root);
	FindPath(SecondVec, second, Root);
	vector<const BinTreeNode *>::const_iterator Firstiter = FirstVec.begin();
	vector<const BinTreeNode *>::const_iterator Seconditer = SecondVec.begin();
	while(Firstiter != FirstVec.end() && Seconditer != SecondVec.end())
	{
		if(*Firstiter != *Seconditer)
			break;
		Firstiter++;
		Seconditer++;
	}
	if(Firstiter == FirstVec.end())
	{
		cout<<"First is the parent of second"<<endl;
		return *(--Firstiter);
	}
	if(Seconditer == SecondVec.end())
	{
		cout<<"Second is the parent of first"<<endl;
		return *(--Seconditer);
	}
	return *(--Firstiter);
}

void FindPath(vector<const BinTreeNode *>& s, ElementType data, const BinTreeNode *Root)//寻找节点,把路径放入容器
{
	const BinTreeNode *pMove(Root);
	while(pMove != NULL)
	{
		if(data < pMove->GetData())
		{
			s.push_back(pMove);
			pMove = pMove->GetLeft();
		}
		else if(data > pMove->GetData())
		{
			s.push_back(pMove);
			pMove = pMove->GetRight();
		}
		else
		{
			s.push_back(pMove);
			break;
		}
	}
}


4、找出二叉树中和为某值的所有路径

void FindSumPath(const BinTreeNode *Root, int sum, vector<ElementType>& path)
{
	bool isleaf(const BinTreeNode *);
	if(!Root)
		return;
	sum -= Root->GetData();
	path.push_back(Root->GetData());
	if(isleaf(Root) && sum == 0)
	{
		for(vector<ElementType>::const_iterator iter = path.begin(); iter != path.end(); ++iter)
			cout<<*iter<<" ";
		cout<<endl;
	}
	if(Root->GetLeft())
	FindSumPath(Root->GetLeft(), sum, path);
	if(Root->GetRight())
	FindSumPath(Root->GetRight(), sum, path);
	sum += Root->GetData();
	path.pop_back();
}
bool isleaf(const BinTreeNode *Root)
{
	return (Root->GetLeft()== NULL && Root->GetRight()== NULL) ? true : false;
}

5、二叉树的镜像

BinTreeNode * TreeMirror(BinTreeNode *Root)
{
	if(Root == NULL)
		return NULL;
	BinTreeNode *temp = Root->GetRight();
	Root->SetRight(Root->GetLeft());
	Root->SetLeft(temp);
	BinTreeNode *Left = TreeMirror(Root->GetLeft());
	Root->SetLeft(Left);
	BinTreeNode *Right = TreeMirror(Root->GetRight());
	Root->SetRight(Right);
	return Root;
}

BinTreeNode *TreeMirror2(BinTreeNode *Root)
{
	if(Root == NULL)
		return NULL;
	else
	{
		TreeMirror2(Root->GetLeft());
		TreeMirror2(Root->GetRight());
		BinTreeNode *temp = Root->GetLeft();
		Root->SetLeft(Root->GetRight());
		Root->SetRight(temp);
		return Root;
	}
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值