java控制檯輸出二叉樹(二叉樹使用鏈式結構存儲)

package com.java.study.datastructuresalgorithms.basisdatastructure.tree;


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.apache.commons.lang3.RandomUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Stack;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 實現自己的二叉樹
 * 鏈式二叉樹,使用鏈式結構存儲數據
 *
 * @author Mr.Xu
 * @date 2020/4/1 21:50
 */
@Data
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class XbLinkedBinaryTree<T> {


    private XbLinkedBinaryTree<T> leftNode;
    private T data;
    private XbLinkedBinaryTree<T> rightNode;
    /**
     * 深度 : 根節點到這個節點所經歷的邊的個數
     * 從上先下遞增,根節點深度爲0
     */
    private int depth;
    /**
     * 層 : 節點的深度 + 1
     */
    private int level;
    /**
     * 高度 : 節點到葉子節點的最長路徑(邊數)
     * 從下向上遞增,最下面高度爲0
     */
    private int height;
    /**
     * 若使用數組存儲二叉樹時,此元素在數組中位置的下標
     */
    private int index;

    /**
     * 使用一組數據隨機的構建一個二叉樹
     *
     * @param t 原始數據
     * @return
     */
    public static <T> XbLinkedBinaryTree<T> build(T[] t) {
        XbLinkedBinaryTree result = null;
        if (t.length > 0) {
            result = XbLinkedBinaryTree.build(0, t.length - 1, t, 0, 1);
        }
        return result;
    }

    private static <T> XbLinkedBinaryTree<T> build(int left, int right, T[] t, int depth, int index) {
        XbLinkedBinaryTree result = null;
        int length = right - left;
        if (length >= 0) {
            /*  選擇此節點的數據索引位置 */
            int pickNumber = RandomUtils.nextInt(left, right + 1);
            XbLinkedBinaryTree<T> leftTree = XbLinkedBinaryTree.build(left, pickNumber - 1, t, (depth + 1), index * 2);
            XbLinkedBinaryTree<T> rightTree = XbLinkedBinaryTree.build(pickNumber + 1, right, t, (depth + 1), (index * 2 + 1));
            int leftTreeHeight = leftTree == null ? 0 : leftTree.getHeight() + 1;
            int rightTreeHeight = rightTree == null ? 0 : rightTree.getHeight() + 1;
            result = new XbLinkedBinaryTree(leftTree, t[pickNumber], rightTree, depth, (++depth), Math.max(leftTreeHeight, rightTreeHeight), index);
        }
        return result;
    }


    public String prettyToString(int unitCharsLength) {
        /*  單個字符的組成方式 */
        String unitChars = Stream.generate(() -> " ").limit(unitCharsLength).collect(Collectors.joining());
        String lineString = Stream.generate(() -> unitChars).limit((int) Math.pow(2, this.height + 2)).collect(Collectors.joining());
        /*  把二叉樹按層打印出來 */
        List<XbLinkedBinaryTree<T>> dataList = new ArrayList();
        dataList.add(this);
        Stream.Builder<String> builder = Stream.builder();
        Optional<XbLinkedBinaryTree<T>> any;
        while ((any = dataList.stream().findAny()).isPresent()) {
            int currentNodeHeight = this.getHeight()-any.get().getDepth();
            int leftLen = (int) Math.pow(2, currentNodeHeight);
            int stepLen = leftLen * 2;
            StringBuffer lineStringBuffer = new StringBuffer(lineString);
            int upLevelCount = (int) Math.pow(2, any.get().getDepth()) - 1;
            dataList = dataList.stream().flatMap(s -> {
                String stringData = s.getData().toString();
                /*  計算此元素在這一行中是第幾個元素,按照滿二叉樹計算 即: null ,null , 2 ,3 ,則, 3 是第四個元素 */
                int lineIndex = s.getIndex() - upLevelCount;
                /*  計算這個元素的首個字符在這一行內是第幾個位置 */
                int start = ((lineIndex - 1) * stepLen + leftLen) * unitChars.length();
                lineStringBuffer.replace(start, start + stringData.length(), stringData);
                Stream<XbLinkedBinaryTree<T>> nodeStream;
                nodeStream = Stream.of(s.getLeftNode(), s.getRightNode()).filter(n -> n != null);
                return nodeStream;
            }).collect(Collectors.toList());
            builder.add(lineStringBuffer.toString()).add("\n");
        }
        return builder.build().collect(Collectors.joining());
    }
    public static void main(String[] args) {
        Integer[] objects = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).toArray(Integer[]::new);
        XbLinkedBinaryTree<Integer> build = XbLinkedBinaryTree.build(objects);
        System.out.println(build.prettyToString(2));
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章