java实现二叉树的三种遍历方式,并把二叉树转为双向链表,输出二叉树

把二叉树转成双向链表

public class TestBinTree {

    private static int[] array={2,3,6,1,4,8,9,5};
    private static List<Node> nodeList=null;
    public static void main(String args[]){
    BinTree bintree=new BinTree();
    bintree.showBinTree(array, 0);
    nodeList=bintree.createBinTree(array, nodeList);
    System.out.println("先序遍历:");
   bintree.first_Traversal(nodeList.get(0));
   System.out.println("\n中序遍历:");
   bintree.order_Traversal(nodeList.get(0));
   System.out.println("\n后序遍历:");
   bintree.after_Traversal(nodeList.get(0));
   Node newNode= bintree.doubleLink(nodeList.get(0));
   System.out.println("\n转为二叉链表后:");
   bintree.showDoubleLink(newNode, true);
    }
}
class BinTree{
      
      public List<Node> createBinTree(int[] array,List<Node> nodeList){//根据数组创建链表
          nodeList=new LinkedList<Node>();
          for(int nodeIndex=0;nodeIndex<array.length;nodeIndex++){
              nodeList.add(new Node(array[nodeIndex]));
          }
          for(int parentIndex=0;parentIndex<array.length/2;parentIndex++){
              if(parentIndex!=array.length/2-1){
                  nodeList.get(parentIndex).left=nodeList.get(parentIndex*2+1);
                  nodeList.get(parentIndex).right=nodeList.get(parentIndex*2+2);
              }else{
                  nodeList.get(parentIndex).left=nodeList.get(parentIndex*2+1);
                  if(array.length%2==1){
                      nodeList.get(parentIndex).right=nodeList.get(parentIndex*2+2);
                  }
              }
          }
          return nodeList;
      }
      public Node doubleLink(Node node){//二叉链表转双向链表
          if(node==null)
              return null;
          Node left=doubleLink(node.left);//把左子树转成二叉链表
          Node right=doubleLink(node.right);//把右子树转成二叉链表
          node.left=null; //释放该节点的左右两子树
          node.right=null;
          if(left!=null){//如果左边不为空的话
          left=LinkNode(left,1);//找到左子节点(已转为二叉链表)的最后端,保存到left中
          node.left=left;//当前的节点的左边指向返回的节点
          left.right=node;//返回的节点的右边指向该节点
          }
          if(right!=null){//这是右边的情况       同上            应该找到右子树(已转成二叉链表)的最左端来链接
          right=LinkNode(right,0);
          node.right=right;
          right.left=node;
          }
          return node;//转成双向链表后返回节点
      }
      public Node LinkNode(Node node,int num){//表示要找到该双向链表需要链接的节点,或是最右端或是最左端  
          if(num==0){//0表示要找到该链表的最左端
             if(node.left==null)
                 return node;
             return LinkNode(node.left,num);
          }else{//表示要找到该链表的最右端
              if(node.right==null)
                  return node;
              return LinkNode(node.right,num);
          }
      }
      public void showDoubleLink(Node node,boolean flag){//输出打印双向链表,flag控制方向,先找到最左的节点
          if(node.left!=null&&flag){//当左节点不为空并且flag为true;时一直往左迭代。直到找到最左点时
              showDoubleLink(node.left,flag);
          }else{//找到最左点了
              flag=false;//把 flag设为false,避免在回调的时候,又跌回来了
              if(node.right!=null){//当右子节点不为空时
                System.out.print(node.data+"=");
                showDoubleLink(node.right,flag);
              }else{//当右子节点为空时,只输出当前节点的值,不再迭代下去了
                System.out.print(node.data+" ");
              }
          }
      }
      public void first_Traversal(Node node){//先序遍历
          if(node!=null){
              System.out.print(node.data+" ");
              first_Traversal(node.left);
              first_Traversal(node.right);
          }
      }
      public void order_Traversal(Node node){//中序遍历
          if(node!=null){
              order_Traversal(node.left);
              System.out.print(node.data+" ");
              order_Traversal(node.right);
          }
      }
      public void after_Traversal(Node node){//后序遍历
          if(node!=null){
              after_Traversal(node.left);
              after_Traversal(node.right);
              System.out.print(node.data+" ");
          }
      }
    public void showBinTree(int[] array,int index){//显示二叉树
          if(array.length>Math.pow(2,index)-1){
             showBinTree(array,index+1);
          }else{
             int totle=(int)Math.pow(2,index);//每行要打行的数
             int linetotle=totle/2;//要打印的节点位置
             int item=0; //要打印的数组的位置
             for(int i=0;i<index;i++){//index表示有多少行
                 boolean flag=false;//控制节点输出
                 for(int j=0;j<totle;j++){
                  if(item<array.length){
                    if(j%linetotle!=0){//决定是输出节点还是空格
                        System.out.print("  ");
                    }else{
                        if(flag==false){
                             System.out.print("  ");
                             flag=true;
                        }else{
                            System.out.print(array[item]>9?array[item]:" "+array[item]);
                            item++;
                            flag=false;
                        }
                    }
                 }else{
                     System.out.print("  ");
                 }  
             }
            linetotle=linetotle/2;
            System.out.println();        
         }
      }
   }
class Node{//表示节点数据结构的类
    Node left;
    Node right;
    int data;
    Node(int newData){
        left=null;
        right=null;
        data=newData;
    }
}

}

最后的效果:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值