首页 > 其他分享 >1.二叉树

1.二叉树

时间:2023-12-06 21:33:05浏览次数:31  
标签:TreeNode cur res 二叉树 null root stack

二叉树

二叉树的种类

满二叉树

满二叉树:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。

完全二叉树

完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层(h从1开始),则该层包含 1~ 2^(h-1) 个节点。

二叉搜索树

二叉搜索树是有数值的了,二叉搜索树是一个有序树

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左、右子树也分别为二叉排序树

平衡二叉搜索树

平衡二叉搜索树:又被称为AVL(Adelson-Velsky and Landis)树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

二叉树的遍历方式

深度优先遍历

image-20231206155409184

前序遍历(中左右)

class Solution {

    public List<Integer> preorderTraversal(TreeNode root) {
       List<Integer> res = new ArrayList<>();
        //preorder(root,res);
        /*
        //迭代法
        if(root == null){
            return res;
        }
        Stack<TreeNode> stack = new Stack<>();
        //中-右-左 入栈
        stack.push(root);
        while(!stack.isEmpty()){
            TreeNode cur= stack.pop();
            res.add(cur.val);
            if(cur.right != null){
                stack.push(cur.right);
            }
            if(cur.left != null){
                stack.push(cur.left);
            }
        }
        */
        //统一迭代
        //要处理的节点放入栈之后,紧接着放入一个空指针作为标记
        if(root == null){
            return res;
        }
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while(!stack.isEmpty()){
            //右-左-中
            TreeNode cur = stack.pop();
            
            if(cur != null){
                if(cur.right!=null){
                    stack.push(cur.right);
                }

                if(cur.left!=null){
                    stack.push(cur.left);
                }

                stack.push(cur);
                //中节点访问过,加空节点标记
                stack.push(null);
                
            }else{//遇到空节点,才把下个节点放进结果集
                cur = stack.peek();
                stack.pop();
                res.add(cur.val);
            }
        }
        return res;

    }

    void preorder(TreeNode root,List<Integer> res){
        if(root == null){
            return;
        }
        //中-左-右
        res.add(root.val);
        preorder(root.left,res);
        preorder(root.right,res);
        
    }
}

中序遍历(左中右)

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        //inorder(root,res);

        /*
        //迭代法,中序需要处理,借助指针
        //左-右 入栈
        if(root == null){
            return res;
        }

        //借用指针的遍历来帮助访问节点,栈则用来处理节点上的元素
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        
        while(cur!=null || !stack.Empty()){
            //当前节点不为空,放入栈且一直走到左 底
            if(cur!=null){
                stack.push(cur);
                cur = cur.left;
            }else{
        //当前节点为空,且栈内有值,弹出上个节点,加入集合,往右走
                //没有右端,会继续弹上个
                //有右端,就会入栈记录,并走到左端底
                cur = stack.pop();//弹的是最左端节点,栈顶是最底端
                res.add(cur.val);
                cur=cur.right;
            }
        }
        */
        //统一迭代
        //要处理的节点放入栈之后,紧接着放入一个空指针作为标记
        if(root == null){
            return res;
        }
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while(!stack.isEmpty()){
            //右-中-左
            TreeNode cur = stack.pop();
            
            if(cur != null){
                if(cur.right!=null){
                    stack.push(cur.right);
                }
                stack.push(cur);
                //中节点访问过,加空节点标记
                stack.push(null);

                if(cur.left!=null){
                    stack.push(cur.left);
                }
            }else{//遇到空节点,才把下个节点放进结果集
                cur = stack.peek();
                stack.pop();
                res.add(cur.val);
            }
        }
        return res;

    }

    void inorder(TreeNode root,List<Integer> res){
        if(root == null){
            return;
        }
        //左-中-右
        inorder(root.left,res);
        res.add(root.val);
        inorder(root.right,res);
        
    }
}

后序遍历(左右中)

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        //postorder(root,res);
        /*
        //迭代法
        if(root == null){
            return res;
        }
        Stack<TreeNode> stack = new Stack<>();
        //中-右-左 入栈
        stack.push(root);
        while(!stack.isEmpty()){
            TreeNode cur= stack.pop();
            res.add(cur.val);
            if(cur.right != null){
                stack.push(cur.right);
            }
            if(cur.left != null){
                stack.push(cur.left);
            }
        }
        //反转
        Collections.reverse(res);
        */
        //统一迭代
        //要处理的节点放入栈之后,紧接着放入一个空指针作为标记
        if(root == null){
            return res;
        }
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while(!stack.isEmpty()){
            //中右左
            TreeNode cur = stack.pop();
            
            if(cur != null){

                stack.push(cur);
                //中节点访问过,加空节点标记
                stack.push(null);

                if(cur.right!=null){
                    stack.push(cur.right);
                }
                
                if(cur.left!=null){
                    stack.push(cur.left);
                }
            }else{//遇到空节点,才把下个节点放进结果集
                cur = stack.peek();
                stack.pop();
                res.add(cur.val);
            }
        }
        return res;

    }

    void postorder(TreeNode root,List<Integer> res){
        if(root == null){
            return;
        }
        
        postorder(root.left,res);
        postorder(root.right,res);
        res.add(root.val);
    }
}

广度优先遍历

层次遍历

class Solution {
    public List<List<Integer>> res = new ArrayList<List<Integer>>();

    public List<List<Integer>> levelOrder(TreeNode root) {
    
        order1(root,0);
        //order2(root);

        return res;
    }
    //DFS-递归法
    public void order1(TreeNode node,Integer deep){
        if(node == null){
            return;
        }
        
        if(res.size() == deep){
            List<Integer> list = new ArrayList<Integer>();
            res.add(list);
        }
        res.get(deep).add(node.val);
        
        deep++;
        order1(node.left,deep);
        order1(node.right,deep);
    }

    //BFS-迭代法,使用队列
    public void order2(TreeNode node){
        if(node == null){
            return;
        }
        Queue<TreeNode> que = new LinkedList<TreeNode>();
        que.offer(node);

        while(!que.isEmpty()){
            List<Integer> list = new ArrayList<Integer>();
            int deep = que.size();

            while(deep> 0){
                TreeNode cur = que.poll();
                list.add(cur.val);
                if(cur.left!=null){
                    que.offer(cur.left);
                }
                if(cur.right!=null){
                    que.offer(cur.right);
                }
                deep--;
            }
            res.add(list);
        }
    }
}

二叉树的定义

public class TreeNode{
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(){}
    TreeNode(int val){this.val = val;}
    TreeNode(int val,TreeNode left,TreeNode rihgt){
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

标签:TreeNode,cur,res,二叉树,null,root,stack
From: https://www.cnblogs.com/autumnmoonming/p/17880587.html

相关文章

  • 第5章. 二叉树
    二叉树一、树的基本概念节点、根节点、父节点、子节点、兄弟节点一棵树可以没有任何节点,称为空树一棵树可以只有一个节点,也就是只有根节点子树、左子树、右子树节点的度:子树的个数树的度:所有节点度中的最大值叶子节点:度为0的节点非叶子节点:度不为0的节点层数:根节点......
  • 17_二叉树的所有路径
    二叉树的所有路径给你一个二叉树的根节点root,按任意顺序,返回所有从根节点到叶子节点的路径。叶子节点是指没有子节点的节点。示例1:输入:root=[1,2,3,null,5]输出:["1->2->5","1->3"]示例2:输入:root=[1]输出:["1"]【思路】题目要求从根节点到叶子的路径,所以需要......
  • 16_平衡二叉树
    平衡二叉树【题外话】二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数。(从上往下看)二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数。(从下往上看)小疑惑:为什么104.二叉树的最大深度中求的是二叉树的最大深度,也用的是后序遍历。(本质上求解的就是根节......
  • 15_完全二叉树的节点个数
    完全二叉树的节点个数给你一棵完全二叉树的根节点root,求出该树的节点个数。完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第h层,则该层包含1~2h个节点。示......
  • 二叉树创建及遍历
    #include<stdio.h>#include<iostream>usingnamespacestd;typedefcharTElemType;typedefvoidStatus;typedefintElemType;typedefstructBiTNode{ TElemTypedata; BiTNode*lchild,*rchild;}BiTNode,*BiTree;voidCreateBiTree(BiTree......
  • C++U5-08-二叉树1
    上节课作业分析讲解视频链接:https://pan.baidu.com/s/1_jaM_TlZmLJX4JbLuJtKzA?pwd=2us4提取码:2us4学习目标  树在C++中,二叉树是一种常用的数据结构,由节点(Node)组成,每个节点可以有最多两个子节点。二叉树具有以下几个主要的作用:存储和组织数据:二叉树可用于存储和组织大......
  • 二叉树
    二叉树分析二叉树的前序,中序,后序的遍历步骤1.创建一颗二叉树2前序遍历2.1先输出当前节点初始的时候是root节点2.2如果左子节点不为空则递归继续前序遍历2.3如果右子节点不为空,则递归继续前序遍历3.中序遍历3.1如果当前节点的左子节点不为空,则递归中序遍历3.2输出当前......
  • 多叉树转二叉树
    CPP代码点击查看代码#include<iostream>#include<queue>#include<stack>usingnamespacestd;//多叉树节点structNode{ stringname;//节点名称 vector<Node*>nodes;//子节点指针数组 // 构造函数 Node(stringname,vector<Node*>nodes):name(n......
  • 查找 - 二叉排序树/平衡二叉树
    二叉排序树性质:中序遍历是递增的查找算法实现BSTreeSearchBST(BSTreeT,KeyTypekey){if(!T||key==T->data)returnT;elseif(key<T->data)returnSearchBST(T->lchild,key);elsereturnSearchBST(T->rchild,key);}算法分析最坏情况:单支树A......
  • 13_翻转二叉树
    翻转二叉树给你一棵二叉树的根节点root,翻转这棵二叉树,并返回其根节点。示例1:输入:root=[4,2,7,1,3,6,9]输出:[4,7,2,9,6,3,1]示例2:输入:root=[2,1,3]输出:[2,3,1]示例3:输入:root=[]输出:[]【思路】基本思想就是想要翻转二叉树,只需要把每一个节点的左右孩子交......