数组转化为二叉树并实现对其遍历

  1. 首先要创建二叉树,将数组以节点的形式存到LinkedList中,然后再根据数组转化为二叉树时节点之间的数字关系构造二叉树.
  2. 实现数组的先序遍历、中序遍历、后续遍历以及广度优先搜索、深度优先搜索等。
  3. 实现广度优先搜索即是层次遍历,需要借用队列先进先出的特点。
  4. 实现深度优先搜索类似于先序遍历,借用栈先进后出的特点。
  5. 实现代码如下:
package tree;

import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;

/**
 *@author xpengfei
 *@creat  10:04:02 AM   Sep 1, 2017
 */
/*
 * 将数组转换为二叉树,并实现对其遍历
 * 广度优先遍历
 * 深度优先遍历
 * 先序遍历、中序遍历、后序遍历
 * 
 * 构造的二叉树: 1  2 3 4 5 6 7 8 9 
 *        先序遍历:DLR 1 2 4 8 9 5 3 6 7 
 *        中序遍历:LDR 8 4 2 9 5 1 6 3 7 
 *        后序遍历:LRD 8 9 4 5 2 6 7 3 1 
 *        
 *        深度优先遍历 1 2 4 8 9 5 3 6 7 
 *        广度优先遍历 1 2 3 4 5 6 7 8 9
 */
public class Array_To_BTree {
    //定义将要被转化的数组
//  private static List<Integer>array=new ArrayList();
    private static int[]array={1,2,3,4,5,6,7,8,9};
    //定义list存储节点
    private static List<Node>nodelist=null;
    //定义内部节点类
    class Node{
        Node lchild=null;//定义左孩子
        Node rchild=null;//定义右孩子
        int data;   //节点存储的数据
        //构造函数,创建节点
        Node(){}
        Node(int data){
            this.data=data;
        }
    }

    /*
     * 创建二叉树的函数createTree
     */
    public void createTree(){
        //首先将数组以节点的形式存到nodelist中,使用LinkedList的原因:LinkedList可以用作栈、队列,插入删除比较便利
        nodelist=new LinkedList();
        for(int i=0;i<array.length;i++){
            nodelist.add(new Node(array[i]));
        }
        /*
         * 其次按照数组转化为二叉树时节点之间的数字关系构造二叉树,根节点为0
         * 最后一个父节点(lastParentNode=array.length/2-1;)有可能不存在右孩子,所以要单独分析
         */
        int lastParentNode=array.length/2-1;    //得到最后一个父节点的数组下标
//      构建前lastParentNode-1个父节点的二叉树关系
        for (int parentIndex = 0; parentIndex < lastParentNode; parentIndex++) {
//          构造左孩子
            nodelist.get(parentIndex).lchild=nodelist.get(parentIndex*2+1);
//          构造右孩子
            nodelist.get(parentIndex).rchild=nodelist.get(parentIndex*2+2);
        }
//      构造最后一个父节点的孩纸
//      左孩子
        nodelist.get(lastParentNode).lchild=nodelist.get(lastParentNode*2+1);
//      右孩子,如果数组长度为奇数则存在右孩子,否则不存在右孩子
        if(array.length%2==1){
            nodelist.get(lastParentNode).rchild=nodelist.get(lastParentNode*2+2);
        }
    }
    /**
     * 先序遍历
     * @param node
     */
    public void preOrderTraverse(Node node){
        if(node==null){
//          System.out.println("树为空!");
            return;
        }
        System.out.print(node.data+"\t");
        preOrderTraverse(node.lchild);
        preOrderTraverse(node.rchild);
    }
    /**
     * 中序遍历
     * @param node
     */
    public void midOrderTraverse(Node node){
        if(node==null){
//          System.out.println("树为空!");
            return;
        }
        midOrderTraverse(node.lchild);
        System.out.print(node.data+"\t");
        midOrderTraverse(node.rchild);
    }
    /**
     * 后序遍历
     * @param node
     */
    public void lastOrderTraverse(Node node){
        if(node==null){
//          System.out.println("树为空!");
            return;
        }
        lastOrderTraverse(node.lchild);
        lastOrderTraverse(node.rchild);
        System.out.print(node.data+"\t");
    }
    /**
     * 广度优先遍历即层次遍历
     * 使用队列
     * 广度优先遍历 1 2 3 4 5 6 7 8 9
     * @param root 根节点
     */
//  public static void visitNode(Node node){
//      System.out.println(node.data+"\t");
//  }
    public void widthOrderTraverse(Node root){
        if(root==null){
            System.out.println("树为空!");
            return;
        }
        Queue<Node>queue=new LinkedList<Node>();
        queue.offer(root);  //将节点插入到队尾
        System.out.println("广度优先遍历:");
        while(!queue.isEmpty()){    //队不为空时一直循环遍历
            Node firstNode=queue.poll();    //移除并返回队头节点
            System.out.print(firstNode.data+"\t");
            if(firstNode.lchild!=null)
                queue.offer(firstNode.lchild);  //左孩子入队
            if(firstNode.rchild!=null)
                queue.offer(firstNode.rchild);  //右孩子入队
        }
        System.out.println();
    }
    /**
     * 深度优先遍历类似于先序遍历
     * 使用栈
     *  深度优先遍历 1 2 4 8 9 5 3 6 7 
     * @param root
     */
    public void depthOrderTraverse(Node root){
        Stack<Node>stack=new Stack();   //定义栈
        if(root==null){
            System.out.println("树为空!");
            return;
        }
        stack.push(root);   //根节点入栈
        System.out.println("深度优先遍历:");
        while(stack.isEmpty()==false){      //栈不为空,则一直循环
            Node node=stack.pop();  //取出栈顶元素
            System.out.print(node.data+"\t");
            if(node.rchild!=null)
                stack.push(node.rchild);    //右孩子入栈
            if(node.lchild!=null)
                stack.push(node.lchild);    //左孩子入栈
        }
        System.out.println();
    }
    public static void main(String[] args) {
        Array_To_BTree array_To_BTree=new Array_To_BTree();
//      array_To_BTree.getArray();
        array_To_BTree.createTree();
//      获取根节点
        Node root =nodelist.get(0);
        System.out.println("先序遍历:");
        array_To_BTree.preOrderTraverse(root);
        System.out.println();
        System.out.println("中序遍历:");
        array_To_BTree.midOrderTraverse(root);
        System.out.println();
        System.out.println("后序遍历:");
        array_To_BTree.lastOrderTraverse(root);
        System.out.println();
        array_To_BTree.widthOrderTraverse(root);
        array_To_BTree.depthOrderTraverse(root);
    }

}
  1. 在代码中使用LinkedList而不是List或ArrayList的原因是:LinkedList添加了可以用作栈、队列或双端队列的方法,在实现插入和删除的时候会更高效。而在实现随机访问的时候ArrayList会更加的高效。
  2. 队列中peek()和element()方法都将在不删除的情况下返回队头,但peek()方法在队列为空时返回的是null而element()方法则是抛出NoSuchElementException异常.
    • poll()和remove()方法都将移除并返回队头,但poll()在队列为空时返回null,而remove()方法则是抛出NoSuchElementException异常
    • offer()方法在允许的情况下将一个元素插入到队尾,或者返回false.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值