首页 > 其他分享 >二叉树遍历

二叉树遍历

时间:2023-01-04 16:13:00浏览次数:38  
标签:right ++ top 遍历 二叉树 BTree root

二叉树遍历

递归遍历

前序

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

相关文章

  • 4 二叉树
      满二叉树:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。深度为k,有2^k-1个节点的二叉树。完全二叉树:在完全二叉树......
  • [算法]图(邻接矩阵)的深度遍历
    packagecom.FeeLang;importjava.util.Scanner;classArcNode{intadjvex;ArcNodenext;}classVertexNode{charvertex;ArcNodefirstedge;}publicclassGraph......
  • C#遍历二叉树
    最近看了一些关于二叉树的文章,于是学习了一下C#遍历二叉树的几种方式,特记录如下二叉树,是一种数据结构,它是一种非线性的数据结构.这里的非线性是相对于线性数据结构而言......
  • React 用axios 获取遍历json 引入swiper轮播图
    结构展示:功能展示:1.使用swiper轮播插件,2.自动轮播,当前图片高亮小按钮首先引入swiper和配置环境1.npminstall--saveswiper2.在src文件夹index.js下引入样式,避免打包失败im......
  • 每日算法之把二叉树打印成多行
    JZ78把二叉树打印成多行题目给定一个节点数为n二叉树,要求从上到下按层打印二叉树的val值,同一层结点从左至右输出,每一层输出一行,将输出的结果存放到一个二维数组中......
  • leetcode-637. 二叉树的层平均值
    637.二叉树的层平均值-力扣(Leetcode)层次遍历+求平均值,Go中的切片也可以模拟queue的功能/***Definitionforabinarytreenode.*typeTreeNodestruct{*......
  • BM33 二叉树的镜像
    题目描述思路分析采用递归的方法,对每一个节点做相同的处理,交换节点位置,也就类似于我们交换两个变量的值一样,需要借助一个临时变量。递归:-传递过来的节点需要做什么......
  • BM32 合并二叉树
    题目描述已知两颗二叉树,将它们合并成一颗二叉树。合并规则是:都存在的结点,就将结点值加起来,否则空的位置就由另一个树的结点来代替。例如:两颗二叉树是:tree1tree2合......
  • CC4 利用指针遍历数组
    描述键盘随机输入6个整数,将这些数据保存到数组中,利用指针遍历数组中的元素并打印。输入描述:键盘随机输入6个整数输出描述:输出数组中的所有元素,每个元素中间使用空......
  • BM31 对称的二叉树
    题目描述思路分析使用递归的方法,每次传递镜像的节点进去,compare函数专门用于比对,对不同的条件做不同的处理代码参考constisSymmetrical=function(pRoot){//w......