数据结构--树,二叉树
树和二叉树用来表示数据之间一对多的关系,而线性表,栈,队列都是线性的数据结构,用来表示一对一的关系。
树只有一个根节点,根也有子节点,子节点又对应多个或者一个子节点。
根节点没有父节点。
同一个节点有可能既是父节点,又是子节点。
普通节点含有子节点,叶子界面没有子节点。
节点:树的基本单位。
节点的度:节点子树的个数。
树的度:所有节点的度的最大值。
叶子节点,无子节点的节点,即度为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]]