数据结构--树,二叉树

时间:2021-10-20 17:30:28

树和二叉树用来表示数据之间一对多的关系,而线性表,栈,队列都是线性的数据结构,用来表示一对一的关系。

树只有一个根节点,根也有子节点,子节点又对应多个或者一个子节点。

根节点没有父节点。

同一个节点有可能既是父节点,又是子节点。

普通节点含有子节点,叶子界面没有子节点。

节点:树的基本单位。

节点的度:节点子树的个数。

树的度:所有节点的度的最大值。

叶子节点,无子节点的节点,即度为0的节点。

分支节点,有子节点的节点为分支节点。

节点层次,根节点1,以此类推。

输的深度:节点最大层次。

有序树:从左到右是有序的为有序树,否则无序树。

祖先节点,当前所在子节点到根节点之间经过的所有节点。

后代节点:以当前节点为根的子节点为后代节点。

森林:多个树的集合。

数据结构--树,二叉树

父节点表示法(代码实现):

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

/**
 * 父节点
 */
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;
        }
        
        @Override
        public String toString() {
            StringBuilder builder = new StringBuilder();
            builder.append("Node [data=")
                .append(data)
                .append(", parent=")
                .append(parent)
                .append("]");
            return builder.toString();
        }
        
    }
    
    private final int deault_tree_size = 1000;
    
    private int treesize = 0;
    
    // 记录所有节点的数组
    private Node<E>[] nodes;
    
    // 节点数目
    private int nodeNums;
    
    public TreeParent(E data) {
        // 初始化数组大小为1000
        treesize = deault_tree_size;
        nodes = new Node[treesize];
        // 定义数组第一个参数为根节点
        nodes[0] = new Node<E>(data, -1);
        nodeNums++;
        
    }
    
    public TreeParent(E data, int tree_size) {
        // 自定义数组长度,即自定义节点数目
        treesize = tree_size;
        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++) {
            // 从根节点开始添加子节点
            if (nodes[i] == null) {
                nodes[i] = new Node(data, pos(parent));
                nodeNums++;
                return;
            }
        }
        throw new RuntimeException("树满了,别加了");
    }
    
    // 根节点都是null了,肯定空的
    public boolean empty() {
        return nodes[0] == null;
    }
    
    // 返回根节点,因为是根节点,所以是第一个元素
    public Node<E> root() {
        return nodes[0];
    }
    
    // 获取指定节点的父节点
    public Node<E> parent(Node node) {
        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;
            int m = nodes[i].parent;
            // 不是根节点的父节点,且节点不为空
            while (m != -1 && nodes[m] != null) {
                m = nodes[m].parent;
                def++;
            }
            if (max < def) {
                max = def;
            }
        }
        return max;
    }
    
    private int pos(Node node) {
        for (int i = 0; i < treesize; i++) {
            if (nodes[i] == node) {
                return i;
            }
        }
        // 根节点
        return -1;
    }
    
    public static void main(String[] args) {
        TreeParent<String> treeParent = new TreeParent<String>("根节点");
        // 获取根节点
        TreeParent.Node root = treeParent.root();
        System.out.println(root.toString());
        System.out.println("-------------------------------------");
        // 根节点添加子节点
        treeParent.addNode("节点1", root);
        treeParent.addNode("节点2", root);
        treeParent.addNode("节点3", root);
        System.out.println("树深度 = " + treeParent.deep());
        System.out.println("-------------------------------------");
        // 获取根节点的所有子节点
        List<Node<String>> nodes = treeParent.children(root);
        System.out.println("获取根节点的所有子节点:" + nodes.toString());
        System.out.println("-------------------------------------");
        Node<String> firstchildren = nodes.get(0);
        treeParent.addNode("nodes.get(0)子节点1", firstchildren);
        treeParent.addNode("nodes.get(0)子节点2", firstchildren);
        treeParent.addNode("nodes.get(0)子节点3", firstchildren);
        System.out.println("nodes.get(0)的所有子节点:"
            + treeParent.children(firstchildren));
        
    }
    
}

 

 结果:

Node [data=根节点, parent=-1]
-------------------------------------
树深度 = 2
-------------------------------------
获取根节点的所有子节点:[Node [data=节点1, parent=0], Node [data=节点2, parent=0], Node [data=节点3, parent=0]]
-------------------------------------
nodes.get(0)的所有子节点:[Node [data=nodes.get(0)子节点1, parent=1], Node [data=nodes.get(0)子节点2, parent=1], Node [data=nodes.get(0)子节点3, parent=1]]