数据结构3—java 树 双亲表示法

假设以一组连续空间存储树的节点,同时在每个节点中,附设一个指示器指示其双亲结点到链表中的 的位置,也就是说,每个结点 知道自己是谁外,还知道双亲在哪里。
双亲表示法根据结点的parent指针很容易找到它的双亲结点,所以时间复杂度为O[1],知道parent为-1,时,表示找到了根节点。可如果要找结点的孩子是什么,需要遍历整个结构才行。

一、定义接口(为什么要用接口~)

http://www.zhihu.com/question/20111251

public interface IBinaryTree<E> {

    /**
     * 添加子节点
     * @param data  数据域
     * @param parent  双亲节点E
     */
    public void addNode(E data,MNode<E>parent);

    /**
     * 获取根节点
     * @return
     */
    public MNode<E> getRoot();

    /**
     * 获取双亲结点
     * @param mNode
     * @return
     */
    public MNode<E>getParent(MNode<E>mNode);


    public List<MNode<E>>getChild(MNode<E>mNode);

    /**
     * 获取全部节点
     * @param mNode
     * @return
     */
    public List<MNode<E>>getTreeNode();

    /**
     * 获取指定结点的位置SDS
     * @param mNode
     * @return
     */
    public int getPos(MNode<E>mNode);

    public int getDeepth();
}

二、自定义Node类

/**
 * 结点结构
 * @author isc
 *
 * @param <T>
 */
public class MNode<E> {

    private E data;//数据域
    private int parent;//双亲

    public E getData() {
        return data;
    }

    public void setData(E data) {
        this.data = data;
    }

    public int getParent() {
        return parent;
    }

    public void setParent(int parent) {
        this.parent = parent;
    }

    public MNode(E data,int parent){
        this.data=data;
        this.parent=parent;
    }

    public MNode(E data) {
        this.data=data;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((data == null) ? 0 : data.hashCode());
        result = prime * result + parent;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        MNode other = (MNode) obj;
        if (data == null) {
            if (other.data != null)
                return false;
        } else if (!data.equals(other.data))
            return false;
        if (parent != other.parent)
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "MNode [data=" + data + ", parent=" + parent + "]";
    }   
}

三、定义树结构

public class MyTree<E> implements IBinaryTree<E>{

    int MAX_TREE_SIZE =100;
    MNode<E>[] nodes; //定义结点数组

    int treeSize;
    int nodeNums=0;

    /**
     * 指定根节点创建树
     * @param data
     */
    public MyTree(E data){

        treeSize = MAX_TREE_SIZE;
        nodes = new MNode[treeSize];  //
        nodes[0] = new MNode<E>(data,-1);//定义根节点
        nodeNums++;
    }

    /**
     * 指定根节点\指定结点数    创建树
     * @param data
     */
    public MyTree(E data,int treeSize){

        this.treeSize = treeSize;
        nodes = new MNode[treeSize];
        nodes[0] = new MNode<E>(data,-1);//定义根节点
        nodeNums++;
    }

    /**
     * 为指定结点添加子节点
     */
    @Override
    public void addNode(E data, MNode<E> parent) {

        for(int i=0;i<treeSize;i++){
            if(nodes[i]==null){
                nodes[i]=new MNode<E>(data, getPos(parent));//指定值和双亲节点
                nodeNums++;
                return;
            }
        }

    }

    @Override
    public MNode<E> getRoot() {
        if(nodeNums>0){
            return nodes[0];
        }
        return null;
    }

    @Override
    public MNode<E> getParent(MNode<E> mNode) {
        return nodes[mNode.getParent()];
    }

    //返回指定节点(非叶节点)的所有子节点
    @Override
    public List<MNode<E>> getChild(MNode<E> parent) {
        List<MNode<E>> list = new ArrayList<MNode<E>>() ;
//      for(int i=0;i<treeSize;i++){
//          if(nodes[i]!=null&&nodes[nodes[i].getParent()].equals(mNode)){
//              list.add(nodes[i]);
//          }
//      }
        for (int i = 0; i < treeSize; i++) {
            if (nodes[i] != null && nodes[i].getParent() == getPos(parent)) {
                list.add(nodes[i]);
            }
        }
        return list;
    }


    @Override
    public int getPos(MNode<E> mNode) {

        for(int i=0;i<treeSize;i++){
            if(nodes[i].equals(mNode)){
                return i;
            }
        }

        return -1;
    }
    @Override
    public int getDeepth() {
        // 用于记录结点的最大深度
        int max = 0;
        for (int i = 0; i < treeSize && nodes[i] != null; i++) {
            // 初始化本结点的深度
            int def = 1;
            // m记录当前结点的父结点的位置
            int m = nodes[i].getParent();
            // 如果其父结点存在
            while (m != -1 && nodes[m] != null) {
                // 向上继续搜索父结点
                m = nodes[m].getParent();
                def++;
            }
            if (max < def) {
                max = def;
            }
        }
        // 返回最大深度
        return max;        
    }

    @Override
    public List<MNode<E>> getTreeNode() {
        List<MNode<E>> list = new ArrayList<MNode<E>>() ;
        for(int i=0;i<treeSize;i++){
            if(nodes[i]!=null){
                list.add(nodes[i]);
            }
        }       
        return list;
    }
}

四、测试类

public class TestClass {

    public static void main(String[] args){
        TestClass ts = new TestClass();
        ts.testTree();
    }

    public void testTree(){
        Student data = new Student();
        data.setId(1);
        data.setName("JY");
        data.setAge(22);

        MyTree<Student> pTree = new MyTree<Student>(data);//利用值创建树

        // 拿到父结点
        MNode<Student> parent = new MNode<Student>(data);
        parent.setParent(-1);

        // 添加子结点
        Student data2 = new Student();
        data2.setId(2);
        data2.setName("LYH");
        data2.setAge(23);        
        pTree.addNode(data2, parent);

        Student data3 = new Student();
        data3.setId(3);
        data3.setName("YC");
        data3.setAge(23);        
        pTree.addNode(data3, parent);

        MNode<Student> parent2 = new MNode<Student>(data2);
        Student data4 = new Student();
        data4.setId(4);
        data4.setName("LAF");
        data4.setAge(23);        
        pTree.addNode(data4, parent2);

        Student data5 = new Student();
        data5.setId(5);
        data5.setName("LAF3");
        data5.setAge(23);        
        pTree.addNode(data5, parent2);

        Student data6 = new Student();
        data6.setId(6);
        data6.setName("LAF3");
        data6.setAge(23);        
        pTree.addNode(data6, parent2);



        // 遍历所有结点
        List<MNode<Student>> children = pTree.getTreeNode();
        System.out.println("树的全部节点为:");
        for(MNode<Student> node : children){
             System.out.println(node.toString());
        }

        System.out.println("树深为:"+pTree.getDeepth());

        List<MNode<Student>> children2 = pTree.getChild(parent2);
        System.out.println("节点为"+pTree.getPos(parent2)+"的子节点为:");

        for (MNode<Student> node : children2) {
            System.out.println(node.toString());
        }
    }
}

五、测试结果

树的全部节点为:
MNode [data=Student [id=1, name=JY, age=22], parent=-1]
MNode [data=Student [id=2, name=LYH, age=23], parent=0]
MNode [data=Student [id=3, name=YC, age=23], parent=0]
MNode [data=Student [id=4, name=LAF, age=23], parent=1]
MNode [data=Student [id=5, name=LAF3, age=23], parent=1]
MNode [data=Student [id=6, name=LAF3, age=23], parent=1]
树深为:3
节点为1的子节点为:
MNode [data=Student [id=4, name=LAF, age=23], parent=1]
MNode [data=Student [id=5, name=LAF3, age=23], parent=1]
MNode [data=Student [id=6, name=LAF3, age=23], parent=1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值