二叉树的先序、中序、后序和中序遍历——Java实现

本文介绍了二叉树的先序、中序、后序及层次遍历算法,并通过Java代码实现了这些遍历方法。此外,还展示了如何构建一棵二叉排序树,并给出了具体的遍历结果示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package treeTraverse;
/**
 * 定义一个树的结点类
 */
public class Node {
    private int data;
    private Node leftChild;
    private Node rightChild;
    
    public Node(){
        
    }

    public Node(int data) {
        super();
        this.data = data;
    }

    public int getData() {
        return data;
    }

    public void setData(int data) {
        this.data = data;
    }

    public Node getLeftChild() {
        return leftChild;
    }

    public void setLeftChild(Node leftChild) {
        this.leftChild = leftChild;
    }

    public Node getRightChild() {
        return rightChild;
    }

    public void setRightChild(Node rightChild) {
        this.rightChild = rightChild;
    }
    
}
package treeTraverse;

import java.util.ArrayList;
import java.util.List;

/**
 * 实现树的先、中、后及层次遍历
 */
public class FindTree {

    private void visit(int data){
        System.out.print(data + "-->");
    }
    //先序遍历
    public void preOrder(Node root){
        if(root == null) return ;
        
        visit(root.getData());
        preOrder(root.getLeftChild());
        preOrder(root.getRightChild());
    }
    //中序遍历
    public void inOrder(Node root){
        if(root == null) return ;
        
        inOrder(root.getLeftChild());
        visit(root.getData());
        inOrder(root.getRightChild());
    }
    //后序遍历
    public void afterOrder(Node root){
        if(root == null) return ;
        
        afterOrder(root.getLeftChild());
        afterOrder(root.getRightChild());
        visit(root.getData());
    }
    
    /**
     * 层次遍历(非递归)
     * 思路:
     * 现将二叉树头结点入队列,然后出队列,访问该结点,
     * 如果它有左子树,则将左子树根节点入队; 
     * 如果它有右子树,则将右子树根节点入队; 
     * 然后出队列,对出队列的结点访问,如此反复,知道队列为空。
     */
    public void levelOrder(Node root){
        
        List<Node> queue = new ArrayList<Node>();
        if(root != null){
            queue.add(root);//将根结点入队
            while(queue.size() != 0){//当队列不空的时候进行循环
                Node q = queue.remove(0);//出队列       返回从列表中移除的元素
                visit(q.getData());//访问该结点
                
                if(q.getLeftChild() != null){//如果它有左子树,则将左子树根节点入队; 
                    queue.add(q.getLeftChild());
                }
                if(q.getRightChild() != null){//如果它有右子树,则将右子树根节点入队;
                    queue.add(q.getRightChild());
                }
            }
        }    
    }
}
package treeTraverse;

/**
 * 构建一个二叉树排序树并测试
 */
public class TestTree {
    public static void main(String[] args) {
        FindTree ft = new FindTree();
        int[] array = {12,76,35,22,16,48,90,46,9,40,90};
        
        Node root = new Node(array[0]);
        for(int i = 1; i < array.length; i++){
            insert(root, array[i]);
        }
        System.out.println("preorder:");  
        ft.preOrder(root);  
        System.out.println("\n"+"inorder:");  
        ft.inOrder(root);  
        System.out.println("\n"+"afterorder:");  
        ft.afterOrder(root);  
        System.out.println("\n"+"levelOrder:");  
        ft.levelOrder(root); 
    }

    /**
     * 构造二叉排序树, 性质如下:
     * 若它的左子树不空,则左子树上所有关键字的值均小于根关键字的值
     * 若它的右子树不空,则右子树上所有关键字的值均小于根关键字的值
     * 如果输出二叉树排序树的中序遍历,则这个序列是递增有序的
     * @param root
     * @param data
     */
    private static void insert(Node root, int data) {
        if(root.getData() < data){
            if(root.getRightChild() == null){
                root.setRightChild(new Node(data));
            }else{
                insert(root.getRightChild(), data);
            }
        }else {
            if(root.getData() > data){
                if(root.getLeftChild() == null){
                    root.setLeftChild(new Node(data));
                }else{
                    insert(root.getLeftChild(), data);
                }
            }
        }
    }
    
}

 
遍历结果:
preorder:
12-->9-->76-->35-->22-->16-->48-->46-->40-->90-->
inorder:
9-->12-->16-->22-->35-->40-->46-->48-->76-->90-->
afterorder:
9-->16-->22-->40-->46-->48-->35-->90-->76-->12-->
levelOrder:
12-->9-->76-->35-->90-->22-->48-->16-->46-->40-->

### 构造二叉树的核心原理 构造二叉树可以通过序遍历序遍历来完成,也可以通过后序遍历序遍历来完成。核心思想在于利用不同遍历方式的特点找到根节点的位置,并以此划分左子树右子树。 #### 方法一:基于序遍历序遍历构建二叉树序遍历中,第一个元素总是当前子树的根节点。而在中序遍历中,根节点左侧的部分表示左子树,右侧部分表示右子树。因此可以递归地分割中列并重建左右子树。 以下是具体实现方法: ```java class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } public class Solution { public TreeNode buildTree(int[] preorder, int[] inorder) { return helper(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1); } private TreeNode helper(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd) { if (preStart > preEnd || inStart > inEnd) { return null; } // 找到根节点 int rootVal = preorder[preStart]; TreeNode root = new TreeNode(rootVal); // 查找根节点在中序遍历中的位置 int index = findIndex(inorder, inStart, inEnd, rootVal); // 计算左子树长度 int leftSize = index - inStart; // 递归构建左子树右子树 root.left = helper(preorder, preStart + 1, preStart + leftSize, inorder, inStart, index - 1); root.right = helper(preorder, preStart + leftSize + 1, preEnd, inorder, index + 1, inEnd); return root; } private int findIndex(int[] array, int start, int end, int value) { for (int i = start; i <= end; i++) { if (array[i] == value) { return i; } } return -1; // 如果未找到则抛异常或处理错误情况 } } ``` 上述代码实现了通过序遍历序遍历构建二叉树的功能[^3]。 --- #### 方法二:基于后序遍历序遍历构建二叉树后序遍历中,最后一个元素始终是当前子树的根节点。同样,在中序遍历中,根节点左侧为左子树,右侧为右子树。这种方法也采用递归来解决问题。 以下是具体的实现方法: ```java public class SolutionPostInOrder { public TreeNode buildTree(int[] postorder, int[] inorder) { return helper(postorder, 0, postorder.length - 1, inorder, 0, inorder.length - 1); } private TreeNode helper(int[] postorder, int postStart, int postEnd, int[] inorder, int inStart, int inEnd) { if (postStart > postEnd || inStart > inEnd) { return null; } // 后序遍历的最后一个是根节点 int rootVal = postorder[postEnd]; TreeNode root = new TreeNode(rootVal); // 寻找根节点在中序遍历中的索引 int index = findIndex(inorder, inStart, inEnd, rootVal); // 左子树大小 int leftSize = index - inStart; // 递归构建右子树左子树(注意后序遍历的方向) root.right = helper(postorder, postEnd - 1 - leftSize + 1, postEnd - 1, inorder, index + 1, inEnd); root.left = helper(postorder, postStart, postEnd - 1 - leftSize, inorder, inStart, index - 1); return root; } private int findIndex(int[] array, int start, int end, int value) { for (int i = start; i <= end; i++) { if (array[i] == value) { return i; } } return -1; } } ``` 此代码展示了如何通过后序遍历序遍历构建二叉树[^2]。 --- ### 思路总结 无论是通过加中还是后序加中的方式,都需要明确以下几点: - **根节点定位**:的第一个元素或者后序的最后一个元素作为根节点。 - **分治法应用**:根据根节点将中划分为两部分,分别对应左子树右子树。 - **递归调用**:不断缩小范围直到无法继续分解为止。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值