java实现树

java实现树,采用链式存储,父节点记录子节点的存储位置。

首先定义一个用于存储子节点位置的节点类

[java]  view plain copy
  1. package my.tree.link;  
  2.   
  3. public class SubNode {  
  4.     private int location;  
  5.     private SubNode next;  
  6.       
  7.     public SubNode(){  
  8.         this.location = 0;  
  9.         this.next = null;  
  10.     }  
  11.     public SubNode(int location){  
  12.         this.location = location;  
  13.         this.next = null;  
  14.     }  
  15.       
  16.     public SubNode(int location, SubNode next){  
  17.         this.location = location;  
  18.         this.next = next;  
  19.     }  
  20.       
  21.     public void setLocation(int location){  
  22.         this.location = location;  
  23.     }  
  24.       
  25.     public int getLocation(){  
  26.         return this.location;  
  27.     }  
  28.       
  29.     public void setNext(SubNode next){  
  30.         this.next = next;  
  31.     }  
  32.       
  33.     public SubNode getNext(){  
  34.         return this.next;  
  35.     }  
  36. }  


然后定义一个用于存储节点信息的节点类

[java]  view plain copy
  1. package my.tree.link;  
  2.   
  3. public class Node<T> {  
  4.     private T data;  
  5.     private SubNode son;  
  6.       
  7.     public Node(){  
  8.           
  9.     }  
  10.       
  11.     public Node(T data){  
  12.         this.data = data;  
  13.         this.son = null;  
  14.     }  
  15.       
  16.     public Node(T data, SubNode son){  
  17.         this.data = data;  
  18.         this.son = son;  
  19.     }  
  20.       
  21.     public void setData(T data){  
  22.         this.data = data;  
  23.     }  
  24.       
  25.     public T getData(){  
  26.         return this.data;  
  27.     }  
  28.       
  29.     public void setSon(SubNode son){  
  30.         this.son = son;  
  31.     }  
  32.       
  33.     public SubNode getSon(){  
  34.         return this.son;  
  35.     }  
  36.       
  37.     @Override  
  38.     public String toString(){  
  39.         return "节点:" + this.data;  
  40.     }  
  41. }  




编写链式存储的树类,这里采用递归求解树的深度(貌似有问题,在求树的深度是,很迷糊)

[java]  view plain copy
  1. package my.tree.link;  
  2.   
  3. import java.util.LinkedList;  
  4. import java.util.List;  
  5.   
  6. public class MyLinkTree<T> {  
  7.     private final int DEFAUL_SIZE = 10;  
  8.     private int size;  
  9.     private int count;  
  10.   
  11.     private Node<T>[] nodes;  
  12.   
  13.     @SuppressWarnings("unchecked")  
  14.     public MyLinkTree() {  
  15.         this.size = this.DEFAUL_SIZE;  
  16.         this.nodes = new Node[this.size];  
  17.         this.count = 0;  
  18.     }  
  19.   
  20.     @SuppressWarnings("unchecked")  
  21.     public MyLinkTree(int size) {  
  22.         this.size = size;  
  23.         this.nodes = new Node[this.size];  
  24.         this.count = 0;  
  25.     }  
  26.   
  27.     public MyLinkTree(T data) {  
  28.         this();  
  29.         Node<T> node = new Node<T>(data);  
  30.         this.nodes[0] = node;  
  31.         this.count++;  
  32.     }  
  33.   
  34.     public MyLinkTree(Node<T> root) {  
  35.         this();  
  36.         this.nodes[0] = root;  
  37.         this.count++;  
  38.     }  
  39.   
  40.     public void add(Node<T> node, Node<T> parent) {  
  41.         SubNode son = new SubNode();  
  42.         for (int i = 0; i < this.size; i++) {  
  43.             if (this.nodes[i] == null) {  
  44.                 this.nodes[i] = node;  
  45.                 son.setLocation(i);  
  46.                 break;  
  47.             }  
  48.         }  
  49.   
  50.         // 往链表中添加子节点位置  
  51.         SubNode next = parent.getSon();  
  52.         if (next != null) {  
  53.             while (next.getNext() != null) {  
  54.                 next = next.getNext();  
  55.             }  
  56.             next.setNext(son);  
  57.         } else {  
  58.             parent.setSon(son);  
  59.         }  
  60.   
  61.         this.count++;  
  62.     }  
  63.   
  64.     public int size() {  
  65.         return this.count;  
  66.     }  
  67.   
  68.     public Node<T> getRoot() {  
  69.         return this.nodes[0];  
  70.     }  
  71.   
  72.     // 获取指定节点的子节点  
  73.     public List<Node<T>> getSon(Node<T> parent) {  
  74.         List<Node<T>> list = new LinkedList<Node<T>>();  
  75.         SubNode son = parent.getSon();  
  76.         while (son != null) {  
  77.             list.add(this.nodes[son.getLocation()]);  
  78.             son = son.getNext();  
  79.         }  
  80.         return list;  
  81.     }  
  82.   
  83.     // 获取树的深度,通过递归的方式来解决  
  84.     public int getDepth(Node<T> node) {  
  85.         SubNode son = node.getSon();  
  86.         if(son == null){  
  87.             return 1;  
  88.         }else{  
  89.             int max = 0;  
  90.             while(son != null){  
  91.                 int temp = this.getDepth(this.nodes[son.getLocation()]);  
  92.                 max = temp > max ? temp : max;  
  93.                 son = son.getNext();  
  94.             }  
  95.             //为什么要max+1?  
  96.             return max+1;  
  97.         }  
  98.     }  
  99.   
  100.     public int deep() {  
  101.         int max = 0;  
  102.         for (int i = 0; i < this.count; i++) {  
  103.             int temp = this.getDepth(this.nodes[i]);  
  104.             max = max > temp ? max : temp;  
  105.         }  
  106.         return max;  
  107.     }  
  108. }  



最后编写一个测试端,用来测试功能是否基本实现

[java]  view plain copy
  1. package my.tree.link;  
  2.   
  3. public class MyLinkTreeClient {  
  4.     public static void main(String[] args) {  
  5.         Node<string> root = new Node<string>("A");  
  6.         Node<string> b = new Node<string>("B");  
  7.         Node<string> c = new Node<string>("C");  
  8.         Node<string> d = new Node<string>("D");  
  9.         Node<string> e = new Node<string>("E");  
  10.         Node<string> f = new Node<string>("F");  
  11.         Node<string> g = new Node<string>("G");  
  12.         Node<string> h = new Node<string>("H");  
  13.         MyLinkTree<string> tree = new MyLinkTree<string>(root);  
  14.         tree.add(b, root);  
  15. //      tree.add(c, root);  
  16. //      tree.add(d, root);  
  17. //      tree.add(e, b);  
  18. //      tree.add(f, b);  
  19. //      tree.add(g, f);  
  20. //      tree.add(h, g);  
  21. //      System.out.println(tree.size());  
  22.         System.out.println(tree.deep());  
  23. //      System.out.println(tree.getSon(b));  
  24.     }  
  25. }


实现一颗树,采用数组的存储方式,将树中的节点用Node类表示,方便与操作。

首先,整棵树的数组结构如下表所示,根节点的无父节点,用“-1”表示。
indexDataparent
0A-1
1B0
2C0
3D0
4E1
5F1
6G5

其次,定义一个节点Node类,用来存储每个节点的内容

[java]  view plain copy
  1. package my.tree;  
  2.   
  3. public class Node<T> {  
  4.     private T data;  
  5.     private int parent;  
  6.       
  7.     public Node(){  
  8.     }  
  9.       
  10.     public Node(T data){  
  11.         this.data = data;  
  12.     }  
  13.       
  14.     public Node(T data,int parent){  
  15.         this.data = data;  
  16.         this.parent = parent;  
  17.     }  
  18.       
  19.     public void setData(T data){  
  20.         this.data = data;  
  21.     }  
  22.       
  23.     public T getData(){  
  24.         return this.data;  
  25.     }  
  26.       
  27.     public void setParent(int parent){  
  28.         this.parent = parent;  
  29.     }  
  30.       
  31.     public int getParent(){  
  32.         return this.parent;  
  33.     }  
  34. }  


开始实现树,提供基本的插入节点、获取所有节点、获取树的深度操作(着重)这些将数组大小设置为2,主要是考虑数组能否自动扩容;

[java]  view plain copy
  1. package my.tree;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Arrays;  
  5. import java.util.List;  
  6.   
  7. public class MyTree<T> {  
  8.     private final int DEFAULT_SIZE = 2;  
  9.     private int size;  
  10.     private int count;  
  11.     private Object[] nodes;  
  12.   
  13.     public MyTree() {  
  14.         this.size = this.DEFAULT_SIZE;  
  15.         this.nodes = new Object[this.size];  
  16.         this.count = 0;  
  17.     }  
  18.   
  19.     public MyTree(Node<T> root) {  
  20.         this();  
  21.         this.count = 1;  
  22.         this.nodes[0] = root;  
  23.     }  
  24.   
  25.     public MyTree(Node<T> root, int size) {  
  26.         this.size = size;  
  27.         this.nodes = new Object[this.size];  
  28.         this.count = 1;  
  29.         this.nodes[0] = root;  
  30.     }  
  31.   
  32.     //添加一个节点  
  33.     public void add(Node<T> node) {  
  34.         for (int i = 0; i < this.size; i++) {  
  35.             if (this.nodes[i] == null) {  
  36.                 nodes[i] = node;  
  37.                 break;  
  38.             }  
  39.         }  
  40.         this.count++;  
  41.     }  
  42.   
  43.     public void check(){  
  44.         if(this.count >= this.size){  
  45.             this.enlarge();  
  46.         }  
  47.     }  
  48.     //添加一个节点,并指明父节点  
  49.     public void add(Node<T> node, Node<T> parent) {  
  50.         this.check();  
  51.         node.setParent(this.position(parent));  
  52.         this.add(node);  
  53.     }  
  54.   
  55.     //获取节点在数组的存储位置  
  56.     public int position(Node<T> node) {  
  57.         for (int i = 0; i < this.size; i++) {  
  58.             if (nodes[i] == node) {  
  59.                 return i;  
  60.             }  
  61.         }  
  62.         return -1;  
  63.     }  
  64.       
  65.     //获取整棵树有多少节点  
  66.     public int getSize(){  
  67.         return this.count;  
  68.     }  
  69.       
  70.     //获取根节点  
  71.     @SuppressWarnings("unchecked")  
  72.     public Node<T> getRoot(){  
  73.         return (Node<T>) this.nodes[0];  
  74.     }  
  75.       
  76.     //获取所以节点,以List形式返回  
  77.     @SuppressWarnings("unchecked")  
  78.     public List<Node<T>> getAllNodes(){  
  79.         List<Node<T>> list = new ArrayList<Node<T>>();  
  80.         for(int i=0;i<this.size;i++){  
  81.             if(this.nodes[i] != null){  
  82.                 list.add((Node<T>)nodes[i]);  
  83.             }  
  84.         }  
  85.         return list;  
  86.     }  
  87.       
  88.     //获取树的深度,只有根节点时为1  
  89.     @SuppressWarnings("unchecked")  
  90.     public int getDepth(){  
  91.           
  92.         int max = 1;  
  93.         if(this.nodes[0] == null){  
  94.             return 0;  
  95.         }  
  96.           
  97.         for(int i=0;i<this.count;i++){  
  98.             int deep = 1;  
  99.             int location = ((Node<T>)(this.nodes[i])).getParent();  
  100.             while(location != -1 && this.nodes[location] != null){  
  101.                 location = ((Node<T>)(this.nodes[location])).getParent();  
  102.                 deep++;  
  103.             }  
  104.             if(max < deep){  
  105.                 max = deep;  
  106.             }  
  107.         }  
  108.         return max;  
  109.     }  
  110.       
  111.     public void enlarge(){  
  112.         this.size = this.size + this.DEFAULT_SIZE;  
  113.         Object[] newNodes = new Object[this.size];  
  114.         newNodes = Arrays.copyOf(nodes, this.size);  
  115.         Arrays.fill(nodes, null);  
  116.         this.nodes = newNodes;  
  117.         System.out.println("enlarge");  
  118.     }  
  119. }  


最后,使用MyTreeClient来测试下,基本功能是否都已经实现;

[java]  view plain copy
  1. package my.tree;  
  2.   
  3. public class MyTreeClient {  
  4.     public static void main(String[] args){  
  5.         Node<String> root = new Node<String>("A",-1);  
  6.         MyTree<String> tree = new MyTree<String>(root);  
  7.         Node<String> b = new Node<String>("B");  
  8.         Node<String> c = new Node<String>("C");  
  9.         Node<String> d = new Node<String>("D");  
  10.         Node<String> e = new Node<String>("E");  
  11.         Node<String> f = new Node<String>("F");  
  12.         Node<String> g = new Node<String>("G");  
  13.         tree.add(b,root);  
  14.         tree.add(c,root);  
  15.         tree.add(d,root);  
  16.           
  17.         tree.add(e,b);  
  18.         tree.add(f,b);  
  19.         tree.add(g,f);  
  20.           
  21.           
  22.         System.out.println(tree.getSize());  
  23.         System.out.println(tree.getRoot().getData());  
  24.         System.out.println(tree.getAllNodes());  
  25.         System.out.println(tree.getDepth());  
  26.         tree.add(new Node<String>("H"),g);  
  27.         System.out.println(tree.getDepth());  
  28.         tree.enlarge();  
  29.     }  
  30. }  
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值