二叉树表示
二叉树的二叉链表表示
#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);
}
}