我们利用栈来实现遍历二叉树
二叉树的创建依然是通过递归实现的,此外我们需要建立一个链栈来压入或弹出每一个元素
先序遍历
1.进栈之前先访问该结点,visit();
2.再继续找其左孩子,直到为NULL为止,然后出栈该元素
3.再判断刚刚出栈元素有没有右孩子,若没有,则继续出栈;若有,则先访问,再进栈
4.若没有右孩子,则出栈;若有,则先访问,再进栈
5.循环下去...
void preOrder(TreeNode* T)
{
//因为要遍历树,所以设置工作指针
TreeNode* node = T;
//因为要压入或弹出元素,所以需要获得栈的头结点
StackNode* head = initStack();
//结点有值或者栈不为空的时候才可以循环
while (node || !isEmpty(head))
{
if (node)//如果node有值
{
visit(node);
push(head, node);
//接着循环,找到最左边的那个结点
node = node->Lchild;
}
else
{
//先出栈,然后寻找右孩子
node = pop(head)->data;
node = node->Rchild;
}
}
}
中序遍历
中序遍历只是将访问visit()调整到出栈之后,其余和先序遍历一样
#include<iostream>
using namespace std;
typedef struct TreeNode
{
char Tdata;
struct TreeNode* Lchild;
struct TreeNode* Rchild;
}TreeNode;
void creatTree(TreeNode** T, char* x, int* index)
{
char temp;
temp = x[*index];
*index += 1;
if (temp == '#')
*T = NULL;
else
{
*T = new TreeNode;
(*T)->Tdata = temp;
creatTree(&(*T)->Lchild, x, index);
creatTree(&(*T)->Rchild, x, index);
}
}
void visit(TreeNode* T)
{
cout << T->Tdata << " ";
}
//利用栈来遍历二叉树
typedef struct StackNode
{
TreeNode* data;
struct StackNode* next;
}StackNode;
StackNode* initStack()
{
StackNode* head = new StackNode;
head->data = NULL;
head->next = NULL;
return head;
}
void push(StackNode* head, TreeNode* T)
{
StackNode* node = new StackNode;
//头插法
node->next = head->next;
head->next = node;
node->data = T;
}
bool isEmpty(StackNode* head)
{
if (head->next == NULL)
return 1;
else
return 0;
}
StackNode* pop(StackNode* head)
{
if (isEmpty(head))
{
return NULL;
}
else
{
//只用拿到第一个结点就行了
StackNode* node = head->next;
head->next = node->next;
return node;
}
}
void preOrder(TreeNode* T)
{
//因为要遍历树,所以设置工作指针
TreeNode* node = T;
StackNode* head = initStack();
//结点有值或者栈不为空的时候才可以循环
while (node || !isEmpty(head))
{
if (node)//如果node有值
{
visit(node);
push(head, node);
//接着循环,找到最左边的那个结点
node = node->Lchild;
}
else
{
//先出栈,然后寻找右孩子
node = pop(head)->data;
node = node->Rchild;
}
}
}
void inOrder(TreeNode* T)
{
//因为要遍历树,所以设置工作指针
TreeNode* node = T;
StackNode* head = initStack();
//结点有值或者栈不为空的时候才可以循环
while (node || !isEmpty(head))
{
if (node)//如果node有值
{
push(head, node);
//接着循环,找到最左边的那个结点
node = node->Lchild;
}
else
{
//先出栈,然后寻找右孩子
node = pop(head)->data;
visit(node);
node = node->Rchild;
}
}
}
int main()
{
char arry[16] = { 'A','B','D','#','#','E','#','#','C','F','#','#','G','#','#' };
TreeNode* T;
int index = 0;
creatTree(&T, arry, &index);
cout << "先序遍历:";
preOrder(T);
cout << endl;
cout << "中序遍历:";
inOrder(T);
cout << endl;
}
后序遍历
#include<iostream>
using namespace std;
typedef struct TreeNode
{
char Tdata;
struct TreeNode* Lchild;
struct TreeNode* Rchild;
bool flag;//0表示没有被访问过
}TreeNode;
void creatTree(TreeNode** T, char* x, int* index)
{
char ch;
ch = x[*index];
*index += 1;
if (ch == '#')
*T = NULL;
else
{
*T= new TreeNode;
(*T)->Tdata = ch;
(*T)->flag = 0;
creatTree(&(*T)->Lchild, x, index);
creatTree(&(*T)->Rchild, x, index);
}
}
void visit(TreeNode* T)
{
cout << T->Tdata << " ";
}
typedef struct StackNode
{
TreeNode* data;
struct StackNode* next;
}StackNode;
StackNode* initStack()
{
StackNode* head = new StackNode;
head->data = NULL;
head->next = NULL;
return head;
}
void push(StackNode* head, TreeNode* T)
{
StackNode* node = new StackNode;
node->data = T;
node->next = head->next;
head->next = node;
}
bool isEmpty(StackNode* head)
{
if (head->next == NULL)
return 1;
else
return 0;
}
StackNode* pop(StackNode* head)
{
if (isEmpty(head))
return NULL;
else
{
StackNode* node = head->next;
head->next = node->next;
return node;
}
}
StackNode* getTop(StackNode* head)
{
if (isEmpty(head))
return NULL;
else
{
StackNode* node = head->next;
return node;
}
}
void postOrder(TreeNode* T)
{
//设置工作指针
TreeNode* node = T;
StackNode* head = initStack();
while (node || !isEmpty(head))//只要结点不为NULL,栈不为NULL
{
if (node)//如果结点不为NULL
{
push(head, node);
node = node->Lchild;
}
else
{
TreeNode* top = getTop(head)->data;//获得当前栈顶元素
if (top->Rchild && top->Rchild->flag == 0)//右孩子不为NULL且没有被访问过
{
top = top->Rchild;
push(head, top);
node = top->Lchild;//再寻找左孩子
}
else
{
top = pop(head)->data;//已经被访问过,不用再入栈,直接出栈
visit(top);
top->flag = 1;//访问后标识
}
}
}
}
int main()
{
char arry[16] = { 'A','B','D','#','#','E','#','#','C','F','#','#','G','#','#' };
TreeNode* T;
int index = 0;
creatTree(&T, arry, &index);
cout << "先序遍历:";
preOrder(T);
cout << endl;
cout << "中序遍历:";
inOrder(T);
cout << endl;
cout << "后序遍历:";
postOrder(T);
cout << endl;
}