【數據結構】樹之父節點表示法和子節點鏈表示法

public class TreeParent<E> {
    public static class Node<T> {
        T data;
        // 記錄其父節點的位置
        int parent;
        public Node () {

        }
        public Node (T data) {
            this.data = data;
        }
        public Node(T data, int parent) {
            this.data   = data;
            this.parent = parent;
        }
        public String toString() {
            return "TreeParent$Node[data=" + data + ", parent=" + parent + "]";
        }
    }

    private final int DEFAULT_TREE_SIZE = 100;
    private int treeSize = 0;
    // 使用一個Node[]數組來記錄該樹裏的全部節點
    private Node<E>[] nodes;
    // 記錄節點數
    private int nodeNums;
    // 以指定根節點建立樹
    public TreeParent(E data) {
        treeSize = DEFAULT_TREE_SIZE;
        nodes = new Node[treeSize];
        nodes[0] = new Node<E>(data, -1);
        nodeNums++;
    }
    // 以指定根節點、指定treeSize建立樹
    public TreeParent(E data, int treeSize) {
        this.treeSize = treeSize;
        nodes = new Node[treeSize];
        nodes[0] = new Node<E>(data, -1);
        nodeNums++;
    }
    // 爲指定節點添加子節點
    public void addNode(E data, Node parent) {
        for (int i = 0; i < treeSize; i++) {
            // 找到數組中第一個爲null的元素,該元素保存新節點
            if (nodes[i] == null) {
                // 建立新節點,並用指定的數組元素保存它
                nodes[i] = new Node(data, pos(parent));
                nodeNums++;
                return;
            }
        }
        throw new RuntimeException("該樹已滿,沒法添加新節點");
    }
    // 判斷樹是否爲空
    public boolean empty() {
        // 根節點是否爲null
        return nodes[0] == null;
    }
    // 返回根節點
    public Node<E> root() {
        return nodes[0];
    }
    // 返回指定節點(非根節點)的父節點
    public Node<E> parent(Node node) {
        // 每一個節點的parent記錄了其父節點的位置
        return nodes[node.parent];
    }
    // 返回指定節點(非葉子節點)的全部子節點
    public List<Node<E>> children(Node parent) {
        List<Node<E>> list = new ArrayList<Node<E>>();
        for (int i = 0; i < treeSize; i++) {
            // 若是當前節點的父節點的位置等於parent節點的位置
            if (nodes[i] != null && nodes[i].parent == pos(parent)) {
                list.add(nodes[i]);
            }
        }
        return list;
    }
    // 返回該樹的深度
    public int deep() {
        // 用於記錄節點最大深度
        int max = 0;
        for (int i = 0; i < treeSize && nodes[i] != null; i++) {
            // 初始化本節點的深度
            int def = 1;
            // m記錄當前節點的父節點的位置
            int m = nodes[i].parent;
            // 若是其父節點存在
            while (m != -1 && nodes[m] != null) {
                // 向上繼續搜索父節點
                m = nodes[m].parent;
                def++;
            }
            if (max < def) {
                max = def;
            }
        }
        // 返回最大深度
        return max;
    }
    // 返回包含指定值的節點
    public int pos(Node node) {
        for (int i = 0; i < treeSize; i++) {
            // 找到指定節點
            if (nodes[i] == node) {
                return i;
            }
        }
        return -1;
    }
}
public class TreeChild<E> {

   private static class SonNode {
       // 記錄當前節點的位置
       private int pos;
       private SonNode next;
       public SonNode(int pos, SonNode next) {
           this.pos = pos;
           this.next = next;
       }
   }
   public static class Node<T> {
       T data;
       // 記錄第一個子節點
       SonNode first;
       public Node(T data) {
           this.data = data;
           this.first = null;
       }
       public String toString() {
           if (first != null) {
               return "ThreeChild$Node[data=" + data + ", first=" + first.pos + "]";
           } else {
               return "ThreeChild$Node[data=" + data + ", first=-1";
           }
       }
   }
   private final int DEFAULT_TREE_SIZE = 100;
   private int treeSize = 0;
   // 使用一個Node[]數組來記錄該樹裏的全部節點
   private Node<E>[] nodes;
   // 記錄節點數
   private int nodeNums;
   // 以指定根節點建立樹
   public TreeChild(E data) {
       treeSize = DEFAULT_TREE_SIZE;
       nodes = new Node[treeSize];
       nodes[0] = new Node<E>(data);
       nodeNums++;
   }
   // 以指定根節點、指定treeSize建立樹
   public TreeChild(E data, int treeSize) {
       this.treeSize = treeSize;
       nodes = new Node[treeSize];
       nodes[0] = new Node<E>(data);
       nodeNums++;
   }
   // 爲指定節點添加子節點
   public void addNode(E data, Node parent) {
       for (int i = 0; i < treeSize; i++) {
           // 找到數組中第一個爲null的元素,該元素保存新節點
           if (nodes[i] == null) {
               // 建立新節點,並用指定數組元素來保存它
               nodes[i] = new Node(data);
               if (parent.first == null) {
                   parent.first = new SonNode(i, null);
               } else {
                   SonNode next = parent.first;
                   while (next.next != null) {
                       next = next.next;
                   }
                   next.next = new SonNode(i, null);
               }
               nodeNums++;
               return;
           }
       }
       throw new RuntimeException("該樹已滿,沒法添加新節點");
   }
   // 判斷樹是否爲空
   public boolean empty() {
       // 根節點是否爲null
       return nodes[0] == null;
   }
   // 返回根節點
   public Node<E> root() {
       // 返回根節點
       return nodes[0];
   }
   // 返回指定節點(非葉子節點)的全部子節點
   public List<Node<E>> children(Node parent) {
       List<Node<E>> list = new ArrayList<Node<E>>();
       // 獲取parent節點的第一個子節點
       SonNode next = parent.first;
       // 沿着孩子鏈不斷搜索下一個孩子節點
       while (next != null) {
           // 添加孩子鏈中的節點
           list.add(nodes[next.pos]);
           next = next.next;
       }
       return list;
   }
   // 返回指定節點(非葉子節點)的第index個子節點
   public Node<E> child(Node parent, int index) {
       // 獲取parent節點的第一個子節點
       SonNode next = parent.first;
       // 沿着孩子鏈不斷搜索下一個孩子節點
       for (int i = 0; next != null; i++) {
           if (index == i) {
               return nodes[next.pos];
           }
           next = next.next;
       }
       return null;
   }
   // 返回該樹的深度
   public int deep() {
       // 獲取該樹的深度
       return deep(root());
   }
   // 遞歸方法:每一個子樹的深度爲其全部子樹的最大深度+1
   private int deep(Node node) {
        if (node.first == null) {
            return 1;
        } else {
            // 記錄其全部子樹的最大深度
            int max = 0;
            SonNode next = node.first;
            // 沿着孩子鏈不斷搜索下一個孩子節點
            while (next != null) {
                // 獲取以其子節點爲根的子樹的深度
                int tmp = deep(nodes[next.pos]);
                if (tmp > max) {
                    max = tmp;
                }
                next = next.next;
            }
            // 最後返回其全部子樹的最大深度 + 1
            return max + 1;
        }
   }
   // 返回包含指定值的節點
   public int pos(Node node) {
        for (int i = 0; i < treeSize; i++) {
            // 找到指定節點
            if (nodes[i] == node) {
                return i;
            }
        }
        return -1;
   }
}
public class TreeTest {
    public static void main(String[] args) {
        TreeParent<String> tp = new TreeParent<String>("root");
        TreeParent.Node root = tp.root();
        System.out.println("初始化後根元素:" + root);
        tp.addNode("節點1", root);
        System.out.println("此樹的深度:" + tp.deep());
        tp.addNode("節點2", root);
        // 獲取全部根節點的全部子節點
        List<TreeParent.Node<String>> nodes = tp.children(root);
        System.out.println("根節點的第一個子節點:" + nodes.get(0));
        // 爲根節點的第一個子節點新增一個子節點
        tp.addNode("節點3", nodes.get(0));
        System.out.println("此樹的深度:" + tp.deep());

        System.out.println("================================");
        TreeChild<String> tc = new TreeChild<String>("root");
        TreeChild.Node tcRoot = tc.root();
        System.out.println("根節點:" + tcRoot);
        tc.addNode("節點1", tcRoot);
        tc.addNode("節點2", tcRoot);
        tc.addNode("節點3", tcRoot);
        System.out.println("添加子節點後的根節點:" + tcRoot);
        System.out.println("此樹的深度:" + tc.deep());
        // 獲取根節點的全部子節點
        List<TreeChild.Node<String>> nodes2 = tc.children(tcRoot);
        System.out.println("根節點的第一個子節點:" + nodes2.get(0));
        // 爲根節點的第一個子節點新增一個子節點
        tc.addNode("節點4", nodes2.get(0));
        System.out.println("根節點的第一個子節點:" + nodes2.get(0));
        System.out.println("此樹的深度:" + tc.deep());
    }
}
相關文章
相關標籤/搜索