树的java底层实现 保存子节点方式和保存父节点方式

本文探讨了使用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;
}

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值