二叉树

二叉树表示

二叉树的二叉链表表示

#include <cstdio>
#include <queue>
#include <stack>
#define ElemType int
#define EndTag 0
using namespace std;

// 二叉树的链式存储
typedef struct Node{
	ElemType data;
	struct Node *left, *right;
} Node, *BinTree;

二叉树的创建

// 初始化二叉树
void InitTree(BinTree &T){
	T = new Node;
	if(T == NULL)
		return;
	T->left = T->right = NULL;
}

// 从文件输入流创建二叉树(前序遍历建立)
void CreateTree(BinTree &T, istream &in)
{
	ElemType e;
	if(in.peek() != EOF)
	{
		in >> e;
		if(e == EndTag)
			T = NULL;
		else{
			T = new Node;T->data = e;
			T->left = T->right = NULL;
			CreateTree(T->left, in);
			CreateTree(T->right, in);
		}
	}
}

二叉树遍历

前序遍历

二叉树前序递归遍历
// 二叉树前序递归遍历
void PreOrder(BinTree &T)
{
	if(T)
	{
		printf("%d ", T->data);
		PreOrder(T->left);
		PreOrder(T->right);
	}
}
二叉树前序非递归遍历
// 二叉树前序非递归遍历
void PreOrder_NR(BinTree &T)
{
	if(T == NULL)
		return;
	stack<Node *> S;
	S.push(T); Node *cur;
	while(!S.empty())
	{
		cur = S.top(); S.pop();
		printf("%d ", cur->data);
		if(cur->right != NULL)
			S.push(cur->right);
		if(cur->left != NULL)
			S.push(cur->left);
	}
}

中序遍历

二叉树中序递归遍历
// 二叉树中序递归遍历
void InOrder(BinTree &T)
{
	if(T)
	{
		InOrder(T->left);
		printf("%d ", T->data);
		InOrder(T->right);
	}
}
二叉树中序非递归遍历
// 二叉树中序非递归遍历
void InOrder_NR(BinTree &T)
{
	stack<Node *> S;
	Node *cur = T;
	while(cur != NULL || !S.empty())
	{
		// 将左子女链上结点全部压栈
		while(cur != NULL)
		{
			S.push(cur);
			cur = cur->left;
		}
		cur = S.top(); S.pop(); 
		printf("%d ", cur->data); 
		cur = cur->right; 
	} 
}

后序遍历

二叉树后序递归遍历
// 二叉树后序递归遍历
void PostOrder(BinTree &T)
{
	if(T)
	{
		PostOrder(T->left);
		PostOrder(T->right);
		printf("%d ", T->data);
	}
}
二叉树后序非递归遍历
前驱指针法
// 二叉树后序非递归遍历(附加前驱指针法)
void PostOrder_NR(BinTree &T)
{
	if(!T)
		return;
	stack<Node *> S; S.push(T);
	Node *cur, *pre = NULL; // 当前指针cur和后序前驱指针pre
	while(!S.empty())
	{
		cur = S.top();
		if(!cur->left && !cur->right)
		{
			// 当前结点两个子树都为空
			S.pop(); printf("%d ", cur->data); 
			pre = cur;
		}else if(pre && (cur->left == pre || cur->right == pre)){
			// 当前结点存在子树不为空,但已被访问过
			S.pop(); printf("%d ", cur->data); 
			pre = cur;
		}else{
			// 当前结点存在子树不为空,并且没有被访问过
			if(cur->right)
				S.push(cur->right); // 右子女不为空,则先将右子女压栈
			if(cur->left)
				S.push(cur->left); // 左子女不为空,则将左子女压栈
		}	
	}
}
重复入栈法
// 二叉树后序非递归遍历(重复入栈法)
void PostOrder_NR2(BinTree &T)
{
	if(!T)
		return;
	stack<Node *> S; S.push(T); S.push(T);
	Node *cur;
	while(!S.empty())
	{
		cur = S.top(); S.pop();
		if(!S.empty() && cur == S.top())
		{
			// 栈不空并且cur是第一次被访问
			if(cur->right)
			{
				S.push(cur->right); S.push(cur->right);
			}
			if(cur->left)
			{
				S.push(cur->left); S.push(cur->left);
			}
		}else
			printf("%d ", cur->data);
	}
}
附加标志法
enum Tag{L,R};

// 附加标志tag用于后序非递归遍历
typedef struct Node{
	ElemType data;
	struct Node *left, *right;
	Tag tag; // 后序非递归遍历的标志位
} Node, *BinTree;
// 二叉树后序非递归遍历(附加tag标志法)
void PostOrder_NR3(BinTree &T)
{
	stack<Node*> S;
	Node *cur = T, *temp; 
	while(cur || !S.empty())
	{
		while(cur)
		{
			cur->tag = L;
			S.push(cur);
			cur = cur->left;
		}
		if(!S.empty())
		{
			temp = S.top();
			if(temp->tag == L)
			{
				temp->tag = R;
				cur = temp->right;
			}else{
				S.pop();
				printf("%d ", temp->data);
			}
		}
	}

}

层次序遍历

// 层次序遍历
void LevelOrder(BinTree &T)
{
	if(!T)
		return;
	queue<Node *> Q;
	Q.push(T); Node *cur;
	while(!Q.empty())
	{
		cur = Q.front(); Q.pop();
		printf("%d ", cur->data);
		if(cur->left)
			Q.push(cur->left);
		if(cur->right)
			Q.push(cur->right);
	}
}
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值