樹的java底層實現 保存子節點方式和保存父節點方式

第一種方式通過保存父節點的方式來實現樹,該種方式的缺陷是每一個節點找到其父節點是比較方便的,但是找每一個節點的子節點是比較困難的,需要遍歷整個數組。

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

//關於樹的建立,我們有兩種方式一個是通過保存子節點的位置的 方式一個是通過保存父節點的方式
public class TreeParent <E>{
//    定義一個子類
    static class Node<T>{
	T data;
	int parent;
//	保存其父節點的位置
	public Node(T data){
	    this.data = data;
	}
	public Node (T data, int parent){
	    this.data = data;
	    this.parent = parent;
	}
	public String toString (){
	    return "date:"+data+"parent:"+parent;
	}
    }
    private final int SIZE = 100;
    private int treeSize = 0;
    private  Node<E>[]nodes;
    private int nodeNums;
//    以指定的根節點創建樹
    public TreeParent (E data){
	treeSize = SIZE;
	nodes = new Node [SIZE];
	nodes[0] = new Node<E>(data,-1);
	nodeNums++;
    }
    // 以指定的的根節點和treeseize來創建一個樹
    public TreeParent (E date,int treeSize){
	this.treeSize = treeSize;
	nodes = new Node [treeSize];
	nodes[0] = new Node<E>(date,-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("該樹已滿無法插入數據");
    }
//    判斷樹是否爲空
    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>> child = new ArrayList<TreeParent.Node<E>>();
	for(int i= 0;i<treeSize;i++){
	    if(nodes[i].parent == pos(parent))
		child.add(nodes[i]);
	}
	return child;
    }
    public int deep (){
	int deep = 0;
	for(int i=0;i<treeSize && nodes[i]!= null;i++){
	    int def = 1;
	    int m = nodes[i].parent;
	    // nodes[m]可能會出現爲null嗎?
	    while (m!=-1 && nodes[m]!= null){
		m = nodes[m].parent;
		def++;
	    }
	    if(def>deep){
		deep = def;
	    }
	}
	return deep;
    }
//	返回包含指定值的節點,根據提供的節點,返回當前節點在當前數組所處的位置
	public int pos (Node node){
	    for(int i= 0;i<treeSize;i++){
		if(node == nodes[i])
		    return i;
	    }
	    return -1;
	}
}
第二種方式保存子節點的方式

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

public class TreeChild <E>{
    
    private static class SonNode{
	private int data;
	private SonNode next;
	public SonNode (int data,SonNode next){
	    this.data = data;
	    this.next = next;
	}
    }
    public static class Node<T>{
	T data;
	SonNode first;
//	create a node
	public Node(T data){
	    this.data = data;
	    this.first = null;
	}
	public String toString (){
	    return data+"";
	}
    }
    private final int TREESIZE = 100;
    private int treeSize = 0;
    private Node []nodes;
    private int nodesNum;
//    create a tree
    public TreeChild (E data){
	treeSize = TREESIZE;
	nodes = new Node[TREESIZE];
	nodes[0] = new Node(data);
	nodesNum ++;
    }
    public TreeChild (E data,int treeSize){
	this.treeSize = treeSize;
	nodes = new Node [treeSize];
	nodes[0] = new Node (data);
	nodesNum++;
    }
//    add a child node 
    public void addChild (E data ,Node parent){
	for(int i= 0;i<treeSize;i++){
	    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 != null){
			next = next.next;
		    }
		    next = new SonNode(i, null);
		    nodesNum++;
		    return;
		}
	    }
	}
	
    }
    
public boolean empty (){
    return nodes[0] ==null;
}
public Node <E>root(){
    return nodes[0];
}
//accoring to an certain node to find all child node
public List <Node<E>> children (Node parent){
    List<Node<E>> list= new ArrayList<Node<E>>();
    SonNode next = parent.first;
    while (next != null){
	list.add(nodes[next.data]);
	next = next.next;
    }
    return list;
}
//return index child node accoring to certain node
public Node<E>child (Node parent,int index){
    SonNode next = parent.first;
    for(int i = 0;next!=null;i++){
	if(index == i)
	    return nodes[next.data];
	next = next.next;
    }
   return null;
}
//cal deep of a tree 
//涉及到遞歸調用的問題了,首先是判斷當前結點的子節點是否爲空,若爲空則直接返回1,如果不是空的話,我們就要對其所有的子節點進行一個遍歷,首先是判斷當前子節點的
//深度,如果當前結點還有子節點,那麼就繼續向下判斷,沒經過一次遞歸都會使當前的深度增加一
public int deep(Node node){
    int max =0;
    int deep = 0;
    SonNode next = node.first;
    if(next == null)
	return 1;
    while (next!=null){
	max = deep(nodes[next.data]);
	if(max >deep)
	    deep = max;
	next = next.next;
    }
    return max+1;
}

}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章