java实现树,采用链式存储,父节点记录子节点的存储位置。
首先定义一个用于存储子节点位置的节点类
- package my.tree.link;
- public class SubNode {
- private int location;
- private SubNode next;
- public SubNode(){
- this.location = 0;
- this.next = null;
- }
- public SubNode(int location){
- this.location = location;
- this.next = null;
- }
- public SubNode(int location, SubNode next){
- this.location = location;
- this.next = next;
- }
- public void setLocation(int location){
- this.location = location;
- }
- public int getLocation(){
- return this.location;
- }
- public void setNext(SubNode next){
- this.next = next;
- }
- public SubNode getNext(){
- return this.next;
- }
- }
然后定义一个用于存储节点信息的节点类
- package my.tree.link;
- public class Node<T> {
- private T data;
- private SubNode son;
- public Node(){
- }
- public Node(T data){
- this.data = data;
- this.son = null;
- }
- public Node(T data, SubNode son){
- this.data = data;
- this.son = son;
- }
- public void setData(T data){
- this.data = data;
- }
- public T getData(){
- return this.data;
- }
- public void setSon(SubNode son){
- this.son = son;
- }
- public SubNode getSon(){
- return this.son;
- }
- @Override
- public String toString(){
- return "节点:" + this.data;
- }
- }
编写链式存储的树类,这里采用递归求解树的深度(貌似有问题,在求树的深度是,很迷糊)
- package my.tree.link;
- import java.util.LinkedList;
- import java.util.List;
- public class MyLinkTree<T> {
- private final int DEFAUL_SIZE = 10;
- private int size;
- private int count;
- private Node<T>[] nodes;
- @SuppressWarnings("unchecked")
- public MyLinkTree() {
- this.size = this.DEFAUL_SIZE;
- this.nodes = new Node[this.size];
- this.count = 0;
- }
- @SuppressWarnings("unchecked")
- public MyLinkTree(int size) {
- this.size = size;
- this.nodes = new Node[this.size];
- this.count = 0;
- }
- public MyLinkTree(T data) {
- this();
- Node<T> node = new Node<T>(data);
- this.nodes[0] = node;
- this.count++;
- }
- public MyLinkTree(Node<T> root) {
- this();
- this.nodes[0] = root;
- this.count++;
- }
- public void add(Node<T> node, Node<T> parent) {
- SubNode son = new SubNode();
- for (int i = 0; i < this.size; i++) {
- if (this.nodes[i] == null) {
- this.nodes[i] = node;
- son.setLocation(i);
- break;
- }
- }
- // 往链表中添加子节点位置
- SubNode next = parent.getSon();
- if (next != null) {
- while (next.getNext() != null) {
- next = next.getNext();
- }
- next.setNext(son);
- } else {
- parent.setSon(son);
- }
- this.count++;
- }
- public int size() {
- return this.count;
- }
- public Node<T> getRoot() {
- return this.nodes[0];
- }
- // 获取指定节点的子节点
- public List<Node<T>> getSon(Node<T> parent) {
- List<Node<T>> list = new LinkedList<Node<T>>();
- SubNode son = parent.getSon();
- while (son != null) {
- list.add(this.nodes[son.getLocation()]);
- son = son.getNext();
- }
- return list;
- }
- // 获取树的深度,通过递归的方式来解决
- public int getDepth(Node<T> node) {
- SubNode son = node.getSon();
- if(son == null){
- return 1;
- }else{
- int max = 0;
- while(son != null){
- int temp = this.getDepth(this.nodes[son.getLocation()]);
- max = temp > max ? temp : max;
- son = son.getNext();
- }
- //为什么要max+1?
- return max+1;
- }
- }
- public int deep() {
- int max = 0;
- for (int i = 0; i < this.count; i++) {
- int temp = this.getDepth(this.nodes[i]);
- max = max > temp ? max : temp;
- }
- return max;
- }
- }
最后编写一个测试端,用来测试功能是否基本实现
- package my.tree.link;
- public class MyLinkTreeClient {
- public static void main(String[] args) {
- Node<string> root = new Node<string>("A");
- Node<string> b = new Node<string>("B");
- Node<string> c = new Node<string>("C");
- Node<string> d = new Node<string>("D");
- Node<string> e = new Node<string>("E");
- Node<string> f = new Node<string>("F");
- Node<string> g = new Node<string>("G");
- Node<string> h = new Node<string>("H");
- MyLinkTree<string> tree = new MyLinkTree<string>(root);
- tree.add(b, root);
- // tree.add(c, root);
- // tree.add(d, root);
- // tree.add(e, b);
- // tree.add(f, b);
- // tree.add(g, f);
- // tree.add(h, g);
- // System.out.println(tree.size());
- System.out.println(tree.deep());
- // System.out.println(tree.getSon(b));
- }
- }
实现一颗树,采用数组的存储方式,将树中的节点用Node类表示,方便与操作。
首先,整棵树的数组结构如下表所示,根节点的无父节点,用“-1”表示。index | Data | parent |
0 | A | -1 |
1 | B | 0 |
2 | C | 0 |
3 | D | 0 |
4 | E | 1 |
5 | F | 1 |
6 | G | 5 |
其次,定义一个节点Node类,用来存储每个节点的内容
- package my.tree;
- public class Node<T> {
- private T data;
- private int parent;
- public Node(){
- }
- public Node(T data){
- this.data = data;
- }
- public Node(T data,int parent){
- this.data = data;
- this.parent = parent;
- }
- public void setData(T data){
- this.data = data;
- }
- public T getData(){
- return this.data;
- }
- public void setParent(int parent){
- this.parent = parent;
- }
- public int getParent(){
- return this.parent;
- }
- }
开始实现树,提供基本的插入节点、获取所有节点、获取树的深度操作(着重)这些将数组大小设置为2,主要是考虑数组能否自动扩容;
- package my.tree;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.List;
- public class MyTree<T> {
- private final int DEFAULT_SIZE = 2;
- private int size;
- private int count;
- private Object[] nodes;
- public MyTree() {
- this.size = this.DEFAULT_SIZE;
- this.nodes = new Object[this.size];
- this.count = 0;
- }
- public MyTree(Node<T> root) {
- this();
- this.count = 1;
- this.nodes[0] = root;
- }
- public MyTree(Node<T> root, int size) {
- this.size = size;
- this.nodes = new Object[this.size];
- this.count = 1;
- this.nodes[0] = root;
- }
- //添加一个节点
- public void add(Node<T> node) {
- for (int i = 0; i < this.size; i++) {
- if (this.nodes[i] == null) {
- nodes[i] = node;
- break;
- }
- }
- this.count++;
- }
- public void check(){
- if(this.count >= this.size){
- this.enlarge();
- }
- }
- //添加一个节点,并指明父节点
- public void add(Node<T> node, Node<T> parent) {
- this.check();
- node.setParent(this.position(parent));
- this.add(node);
- }
- //获取节点在数组的存储位置
- public int position(Node<T> node) {
- for (int i = 0; i < this.size; i++) {
- if (nodes[i] == node) {
- return i;
- }
- }
- return -1;
- }
- //获取整棵树有多少节点
- public int getSize(){
- return this.count;
- }
- //获取根节点
- @SuppressWarnings("unchecked")
- public Node<T> getRoot(){
- return (Node<T>) this.nodes[0];
- }
- //获取所以节点,以List形式返回
- @SuppressWarnings("unchecked")
- public List<Node<T>> getAllNodes(){
- List<Node<T>> list = new ArrayList<Node<T>>();
- for(int i=0;i<this.size;i++){
- if(this.nodes[i] != null){
- list.add((Node<T>)nodes[i]);
- }
- }
- return list;
- }
- //获取树的深度,只有根节点时为1
- @SuppressWarnings("unchecked")
- public int getDepth(){
- int max = 1;
- if(this.nodes[0] == null){
- return 0;
- }
- for(int i=0;i<this.count;i++){
- int deep = 1;
- int location = ((Node<T>)(this.nodes[i])).getParent();
- while(location != -1 && this.nodes[location] != null){
- location = ((Node<T>)(this.nodes[location])).getParent();
- deep++;
- }
- if(max < deep){
- max = deep;
- }
- }
- return max;
- }
- public void enlarge(){
- this.size = this.size + this.DEFAULT_SIZE;
- Object[] newNodes = new Object[this.size];
- newNodes = Arrays.copyOf(nodes, this.size);
- Arrays.fill(nodes, null);
- this.nodes = newNodes;
- System.out.println("enlarge");
- }
- }
最后,使用MyTreeClient来测试下,基本功能是否都已经实现;
- package my.tree;
- public class MyTreeClient {
- public static void main(String[] args){
- Node<String> root = new Node<String>("A",-1);
- MyTree<String> tree = new MyTree<String>(root);
- Node<String> b = new Node<String>("B");
- Node<String> c = new Node<String>("C");
- Node<String> d = new Node<String>("D");
- Node<String> e = new Node<String>("E");
- Node<String> f = new Node<String>("F");
- Node<String> g = new Node<String>("G");
- tree.add(b,root);
- tree.add(c,root);
- tree.add(d,root);
- tree.add(e,b);
- tree.add(f,b);
- tree.add(g,f);
- System.out.println(tree.getSize());
- System.out.println(tree.getRoot().getData());
- System.out.println(tree.getAllNodes());
- System.out.println(tree.getDepth());
- tree.add(new Node<String>("H"),g);
- System.out.println(tree.getDepth());
- tree.enlarge();
- }
- }