二叉树遍历
递归遍历
前序
void preOrder(BTree root){
if(root == NULL)
return ;
visit(root);
preOrder(root->left);
preOrder(root->right);
}
后序
void postOrder(BTree root){
if(root == NULL){
return ;
}
postOrder(root->left);
postOrder(root->right);
visit(root);
}
中序
void inOrder(BTree root){
if(root == NULL)
return ;
inOrder(root->left);
visit(root);
inOrder(root->right);
}
非递归遍历
前序
借助栈来实现,注意左右孩子的入栈顺序
先右孩子,再左孩子,这样出栈的时候就是先左再右
void preOrder(BTree root){
BTree stack[MaxSize];
int top = -1;
BTree p = NULL;
if(root) //根节点不为空 将其入栈
stack[++top] = root;
while(top != -1){
p = stack[top--]; //弹出栈顶节点并访问
visit(p);
if(p->right) //先右孩子
stack[++top] = p->right;
if(p->left) //再左孩子
stack[++top] = p->left;
}
}
后序
版本一
在非递归先序遍历的基础上实现
先序:根左右
后序:左右根
逆后序:根右左
可以得知,逆后序和先序遍历序列仅仅是左右顺序不同
而在先序遍历算法中,左右的顺序取决于将左右孩子入栈的顺序,因此调换先序遍历算法中左右孩子入栈顺序,即先左孩子入栈,再右孩子入栈即可得逆后序遍历序列,再将逆后序遍历序列反转即可得后序。
void postOrder(BTree root){
BTree s1[MaxSize]; //栈1用来得逆后序
int top1 = -1;
BTree s2[MaxSize]; //栈2用来反转逆后序
int top2 = -1;
BTree p = NULL;
if(root)
s1[++top1] = root;
while(top1 != -1){
p = s1[top1--];
s2[++top2] = p;
if(p->left){
s1[++top1] = p->left;
}
if(p->right){
s1[++top1] = p->right;
}
}//遍历完成s2中存放即为后序遍历序列
while(top2 != -1){
visit(s2[top2--]);
}
}
版本二
借助栈和尾指针模拟后序遍历流程,先左再根再右
-
从根节点开始,沿左孩子依次入栈,直到左孩子为空
-
取栈顶节点p
-
根据p右孩子的情况进行处理
-
p没有右孩子
弹出并访问p
-
p有右孩子
-
右孩子已被访问过
弹出并访问p
-
右孩子未被访问过
转去右孩子执行
-
-
void postOrder(BTree root){
BTree stack[MaxSize];
int top = -1;
BTree p = root; //当前指针p 初始为根节点
BTree r = NULL; //尾指针r 初始为空
while(p || top != -1){
if(p){
stack[++top] = p;
p = p->left;
}
else{
p = stack[top]; //读栈顶节点p
if(p->right && r->right != r){ //判断是否要转去右孩子执行
p = p->right;
}
else{
top--; //弹出栈顶节点并访问
visit(p);
r = p; //r记录上一次访问过的节点
p = NULL; //每次访问完p都要置空
}
}
}
}
后序遍历版本二算法可以应用在求从根节点到树中某个节点的路径
当访问到某个节点时,当前栈中存放的节点即为从根节点到该节点的路径
中序
生疏,重点理解记忆
void inOrder(BTree root){
BTree stack[MaxSize];
int top = -1;
BTree p = root;
while(p || top != -1){
if(p){ //这段逻辑和后序相同,一直往左走
stack[++top] = p;
p = p->left;
}
else{ //左边走到头不需要再判断右孩子,直接访问然后转去右子树即可
visit(stack[top]);
p = stack[top]->right;
top--;
}
}
}
层序
void levelOrder(BTree root){
BTree que[MaxSize];
int front = 0, rear = 0;
BTree p = NULL;
if(root){
que[rear++] = root;
}
while(front != rear){
p = que[front++];
visit(p);
if(p->left){
que[rear++] = p->left;
}
if(p->right){
que[rear++] = p->right;
}
}
}
标签:right,++,top,遍历,二叉树,BTree,root
From: https://www.cnblogs.com/dctwan/p/17025150.html