树-孩子兄弟表示法的实现
2017-12-26 20:08
232 查看
1.什么是树
树状图是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:每个节点有零个或多个子节点;没有父节点的节点称为根节点;每一个非根节点有且只有一个父节点;除了根节点外,每个子节点可以分为多个不相交的子树;
图解(灵魂画师)
2.树的相关知识
节点的度:一个节点含有的子树的个数称为该节点的度;叶节点或终端节点:度为0的节点称为叶节点;
非终端节点或分支节点:度不为0的节点;
双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点;
孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点;
兄弟节点:具有相同父节点的节点互称为兄弟节点;
树的度:一棵树中,最大的节点的度称为树的度;
节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;
树的高度或深度:树中节点的最大层次;
堂兄弟节点:双亲在同一层的节点互为堂兄弟;
节点的祖先:从根到该节点所经分支上的所有节点;
子孙:以某节点为根的子树中任一节点都称为该节点的子孙。
森林:由m(m>=0)棵互不相交的树的集合称为森林;
遍历表达法有3种方法:先序遍历、中序遍历、后序遍历
定义一棵树的根结点层次为1,其他节点的层次是其父结点层次加1。一棵树中所有结点的层次的最大值称为这棵树的深度。
3.树的实现
树的实现主要有三个:1.父节点表示法:该方法主要思路是,每个节点存储父节点的位置,这样就构成一棵树
2.孩子链表示法:该方法的主要思路是,每个节点用数组存储孩子位置,不过这个表示法有个致命的缺陷,就是造成大量空间上的浪费,因为数组最大的长度必定和最多的度相等,但是并不是每个子树都有那么多度,所以造成空间上的浪费;
3.兄弟孩子节点表示法:该方法主要思路是:每个节点存储孩子,兄弟节点位置,本次就用这个表示法实现
下面代码只实现了添加功能,有空再补上其他功能,其他功能也是大同小异,至于为什么有个flag变量,因为我觉得树里存在重复的变量,所以用flag来唯一标识一个树
package Tree; /* * 树的整体 * @author WLNSSS * @time 2017.12.22 * */ public class MyTree<T> { // 记录根树 private Node root; // 记录节点数 private int nodeCount; // 记录节点标识的位置 private int superFlag; public MyTree(T data) { //初始化,构造器先装配一个根节点 root = new Node(data); } // 在指定位置添加节点 public void add(T data, int flag) { // 定位到指定的位置 Node point = getNodePost(flag); // 错误检查,判断是否是空,如果空抛出异常 if (point == null) { throw new NullPointerException("没有此元素"); } else { // 判断孩子节点空或非空,然后进行不同的操作 if (point.getChlid() == null) { point.setChlid(new Node(data)); } if (point.getChlid() != null) { Node temp = point.getChlid(); Node newNode = new Node(data); newNode.setBrother(temp); point.setChlid(newNode); } // 元素标识+1 flag++; } } // 定位节点位置,找出该节点 public Node getNodePost(int flag) { // 调用另外一个复用方法实现 return getNodePost(flag, root); } // 定位节点位置,找出该节点 private Node getNodePost(int flag, Node ponit) { // 节点指针,先从root节点开始递归 Node point = root; // 当递归到一个元素的flag等于要查找的flag则返回当前的指针 if (point.flag == flag) { return point; } // 若兄弟节点非空,则递归取出元素 if (point.getBrother() != null) { return getNodePost(flag, point.getBrother()); } // 若子节点非空,则递归取出元素 if (point.getChlid() != null) { return getNodePost(flag, ponit.getChlid()); } // 若没找到则返回null return null; } /* * 树的节点(内部类) */ private class Node { // 存储的数据 T data; // 子节点位置 Node chlid; // 兄弟节点位置 Node brother; // 唯一标识该节点的变量 int flag; public T getData() { return data; } public void setData(T data) { this.data = data; } public Node getChlid() { return chlid; } public void setChlid(Node chlid) { this.chlid = chlid; } public Node getBrother() { return brother; } public void setBrother(Node brother) { this.brother = brother; } public Node(T data) { this(data, null, null,superFlag); } public Node(T data, Node chlid, Node brother,int flag) { this.data = data; this.chlid = chlid; this.brother = brother; this.flag = flag; } } public static void main(String[] args) { MyTree<Integer> myTree = new MyTree(12); myTree.add(1,0); myTree.add(2,0); System.out.println(myTree.root.chlid.brother.getData()); } }
相关文章推荐
- 使用C++ 和 孩子兄弟表示法实现树
- 孩子兄弟表示法实现树
- DELPHI 孩子兄弟表示法 (递归实现)
- 树的孩子兄弟表示法 及遍历实现
- 左孩子右兄弟表示多叉树查找返回下一个节点
- poj 1470 Closest Common Ancestors tarjan求lca和树的孩子兄弟表示
- 将邻接表表示的图转换为孩子兄弟法表示的二叉树
- 第六章(5).树的孩子兄弟表示法
- 随意有根树的左孩子右兄弟表示法存储
- 软件设计师2006年11月下午试题5(C语言 树及其孩子-兄弟表示)
- 左孩子右兄弟二叉树实现家族家谱
- 构建树(孩子兄弟表示法)
- 以孩子兄弟链表表示法为存储结构,求树的深度和度。
- 数据结构——树的孩子兄弟表示法
- 树的左孩子 右兄弟表示法的建立过程 (后序遍历)
- 普通二叉树转二叉链表(孩子兄弟表示法)
- 树的括号表示+树的孩子表示线性结构实现
- VC++ 树的孩子兄弟表示法
- 普通二叉树转二叉链表(孩子兄弟表示法)
- 树的孩子兄弟表示法