二叉树的存储方式和遍历方式

Posted dxj1016

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的存储方式和遍历方式相关的知识,希望对你有一定的参考价值。

二叉树的存储方式

链式存储

链式存储就是使用指针,通过指针把分布在散落在各个地址的结点串联一起。

链式存储的二叉树数据结构:

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

顺序存储

顺序存储的方式是用数组,顺序存储的元素在内存是连续分布的

用数组来存储二叉树如何遍历的?

如果父结点的数组下标是i,那么他的左孩子就是i*2+1,右孩子就是i * 2+2;

二叉树的遍历方式

遍历方式

  • 深度优先遍历:先往深走,遇到叶子结点再往回走
    • 前序遍历(递归法,迭代法)
    • 中序遍历(递归法,迭代法)
    • 后序遍历(递归法,迭代法)
  • 广度优先遍历:一层一层的去遍历
    • 层次遍历(迭代法)

在深度优先遍历中:有三个顺序,前中后序遍历, 有同学总分不清这三个顺序,经常搞混,我这里教大家一个技巧。

深度优先遍历的实现

144. 二叉树的前序遍历

 /**
     * 递归排序--前序遍历
     * @param head
     */
    ArrayList<Integer> preOrderReverse(Node head)
        ArrayList<Integer> result=new ArrayList<Integer>();
        preOrderRecur(head,rusult);
        return result;
    
 /**
     * 前序遍历的实现
     * @param head
     */
    public static void preOrderRecur(Node head,ArrayList<Integer> result) 
        if (head == null) 
            return;
        
        result.add(head.value);
        preOrderRecur(head.left,result);
        preOrderRecur(head.right,result);

    
/**
     * 非递归排序--前序遍历
     * 前头结点进栈,然后打印,然后右孩子进栈,然后左孩子进栈。
     * 前序遍历是中左右,先访问的是中间结点,要处理的元素也是中间结点
     * 要访问的元素和要处理的元素顺序是一致的,都是中间结点。
     * @param head
     */
    public static List<Integer> preOrderUnRecur(Node head) 
        List<Integer> result=new ArrayList<>();
        System.out.println("pre-order: ");
        if (head != null) 
            Stack<Node> stack = new Stack<Node>();
            stack.add(head);
            while (!stack.isEmpty()) 
                head = stack.pop();
                result.add(head.value);
                if (head.right != null) 
                    stack.push(head.right);
                
                if (head.left != null) 
                    stack.push(head.left);
                
            
            return result;
        
    

94. 二叉树的中序遍历

/**
     * 递归排序--中序遍历
     * @param head
     */
    public  List<Integer> InOrderReverse(Node head)
        List<Integer> result=new ArrayList<Integer>();
        inOrderRecur(head,rusult);
        return result;
    
 /**
     * 中序遍历的实现
     * @param head
     */
    public static void inOrderRecur(Node head,List<Integer> list) 
        if (head == null) 
            return;
        
        inOrderRecur(head.left,list);
        list.add(head.val);
        inOrderRecur(head.right,list);
    
/**
     * 非递归排序--中序遍历
     * 一开始栈为空,看栈和二叉树是否为空
     * 如果二叉树不为空,就头结点进栈,接着左孩子进栈
     * 如果二叉树为空,那么出栈并打印,然后右孩子进栈
     * 中序遍历是左中右,先访问二叉树顶部结点,然后一层一层向下访问,直到到达树左边的最底部,再开始处理结点(也就是把结点的数值放进result数组中),这就造成了处理顺序和访问顺序是不一致的
     * @param head
     */
    public static List<Integer> inOrderUnRecur(Node head) 
        List<Integer> result=new ArrayList<>();
        System.out.println("in-order");
        if (head != null) 
            Stack<Node> s = new Stack<>();
            while (!s.isEmpty() || head != null) 
                if (head != null) 
                    s.push(head);
                    head = head.left;
                 else 
                    head = s.pop();
                    result.add(head.value);
                    head = head.right;
                
            
            return result;
        
    

145. 二叉树的后序遍历

/**
     * 递归排序--后序遍历
     * @param head
     */
    public  List<Integer> PosOrderReverse(Node head)
        List<Integer> result=new ArrayList<Integer>();
        PosOrderRecur(head,rusult);
        return result;
    
 /**
     * 后序遍历的实现
     * @param head
     */   
    public static void posOrderRecur(Node head) 
        if (head == null) 
            return;
        
        posOrderRecur(head.left,result);
        posOrderRecur(head.right,result);
        list.add(head.value);
    
/**
     * 非递归排序--后序遍历
     * 头结点进栈,然后看栈是否为空,不为空就出栈,并且进入第二个栈
     * 然后看左孩子进栈,然后右孩子进栈
     * 最后第二个栈全部出栈,并打印
     * @param head
     */
    public static List<Integer> posOrderUnRecur(Node head) 
        List<Integer> result=new ArrayList<>();
        System.out.println("pos-order: ");
        if (head != null) 
            Stack<Node> s1 = new Stack<>();
            Stack<Node> s2 = new Stack<>();
            s1.push(head);
            while (!s1.isEmpty()) 
                head = s1.pop();
                s2.push(head);
                if (head.left != null) 
                    s1.push(head.left);
                
                if (head.right != null) 
                    s1.push(head.right);
                
            
            while (!s2.isEmpty()) 
                head = s2.pop();
                result.add(head.value);
            
        
        return result;
    

*589. N 叉树的前序遍历

/*
// Definition for a Node.
class Node 
    public int val;
    public List<Node> children;

    public Node() 

    public Node(int _val) 
        val = _val;
    

    public Node(int _val, List<Node> _children) 
        val = _val;
        children = _children;
    
;
*/

class Solution 
    public List<Integer> preorder(Node root) 
        Stack<Node> stack=new Stack<>();
        List<Integer> list=new LinkedList<>();
        if(root==null)
            return list;
        
        stack.push(root);
        while(!stack.isEmpty())
            Node node=stack.pop();
            list.add(node.val);
            Collections.reverse(node.children);
            stack.addAll(node.children);
        
        return list;   
    

*590. N 叉树的后序遍历

/*
// Definition for a Node.
class Node 
    public int val;
    public List<Node> children;

    public Node() 

    public Node(int _val) 
        val = _val;
    

    public Node(int _val, List<Node> _children) 
        val = _val;
        children = _children;
    
;
*/

class Solution 
    List<Integer> list = new ArrayList<Integer>();
    public List<Integer> postorder(Node root) 
        if (root == null)
            return list;
        for (Node node : root.children)
            postorder(node);
        list.add(root.val);
        return list;
    
    

广度优先遍历的实现

102. 二叉树的层序遍历

/**
 * Definition for a binary tree node.
 * public class TreeNode 
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() 
 *     TreeNode(int val)  this.val = val; 
 *     TreeNode(int val, TreeNode left, TreeNode right) 
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     
 * 
 */
class Solution 
    public List<List<Integer>> levelOrder(TreeNode root) 
        List<List<Integer>> lists=new ArrayList<>();
        if(root==null)
            return lists;
        
        List<TreeNode> stack=new ArrayList<>();
        stack.add(root);
        while(!stack.isEmpty())
            int size=stack.size();
            List<Integer> list=new ArrayList<>();
            for(int i=0;i<size;i++)
                TreeNode remvoe=stack.remove(0);
                list.add(remvoe.val);
                if(remvoe.left!=null)
                    stack.add(remvoe.left);
                
                if(remvoe.right!=null)
                    stack.add(remvoe.right);
                
            
            lists.add(list);
        
        return lists;
    

107. 二叉树的层序遍历 II

思路:相对于102.二叉树的层序遍历,就是最后把数组反转一下就可以了。也可以直接在加入数组的时候从后面加

/**
 * Definition for a binary tree node.
 * public class TreeNode 
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() 
 *     TreeNode(int val)  this.val = val; 
 *     TreeNode(int val, TreeNode left, TreeNode right) 
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     
 * 
 */
class Solution 
    public List<List<Integer>> levelOrderBottom(TreeNode root) 
        List<List<Integer>> lists=new LinkedList<>();
        if(root==null)
            return lists;
        
        List<TreeNode> listTree=new LinkedList<>();
        listTree.add(root);
        while(!listTree.isEmpty())
            int size=listTree.size();
            List<Integer> list=new ArrayList<>();
            for(int i=0;i<size;i++)
                TreeNode node=listTree.remove(0);
                list.add(node.val);
                if(node.left!=null)
                    listTree.add(node.left);;
                
                if(node.right!=null)
                    listTree.add(node.right);
                
            
            lists.add(0,list);
        
     
        return lists;
    



199. 二叉树的右视图

思路:层序遍历的时候,判断是否遍历到单层的最后面的元素,如果是,就放进result数组中,随后返回result就可以了。

/**
 * Definition for a binary tree node.
 * public class TreeNode 
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() 
 *     TreeNode(int val)  this.val = val; 
 *     TreeNode(int val, TreeNode left, TreeNode right) 
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     
 * 
 */
class Solution 
    public List<Integer> rightSideView(TreeNode root) 
        List<Integer> list=new ArrayList<>();
        if(root==null)
            return list;
        
        List<TreeNode> listTree=new ArrayList<>();
        listTree.add(root);
        while(!listTree.isEmpty())
            int size=listTree.size();
            for(int i=0;i<size;i++)
                TreeNode remove=listTree.remove(0);
                if(i==size-1)
                    list.add(remove.val);
                
                if(remove.left!=null)
                    listTree.add(remove.left);;
                
                if(remove.right!=null)
                    listTree.add(remove.right);
                
            
        
        return list;
    

637. 二叉树的层平均值

思路:本题就是层序遍历的时候把一层求个总和在取一个均值。

/**
 * Definition for a binary tree node.
 * public class TreeNode 
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() 
 *     TreeNode(int val)  this.val = val; 
 *     TreeNode(int val, TreeNode left, TreeNode right) 
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     
 * 
 */
class Solution 
    public List<Double> averageOfLevels(TreeNode root) 
        List<TreeNode> stack=new LinkedList<>();
        List<Double> list=new LinkedList<>();

以上是关于二叉树的存储方式和遍历方式的主要内容,如果未能解决你的问题,请参考以下文章

二叉树的存储方式和遍历方式

二叉树的存储方式和遍历方式

急!二叉树的存储结构,并完成:建立、查找、计算结点数、求高度、三种遍历方式

JAVA数据结构与算法之顺序存储二叉树

二叉树的存储方式以及递归和非递归的三种遍历方式

二叉树概念及其三种遍历方式实现