基于链表节点实现二叉树节点
2016-03-19 20:29
155 查看
package codes04; /* * 二叉树节点ADT接口 */ public interface BinTreePosition extends Position{ // 判断是否有父节点 public boolean hasParent(); // 返回当前节点的父节点 public BinTreePosition getParent(); // 设置当前节点的父节点 public void setParent(BinTreePosition p); // 判断是否为叶子节点 public boolean isLeaf(); // 判断是否为左孩子 public boolean isLChild(); // 判断是否有左孩子 public boolean hasLChild(); // 返回当前节点的左孩子 public BinTreePosition getLChild(); // 设置当前节点的左孩子 (this.lChild和c.parent都不一定为空) public void setLChild(BinTreePosition c); //判断是否为右孩子 public boolean isRChild(); // 判断是否有右孩子 public boolean hasRChild(); // 返回当前节点的右孩子 public BinTreePosition getRChild(); // 设置当前节点的右孩子,(注:this.rChild和c.parent都不一定为空) public void setRChild(BinTreePosition c); // 返回当前节点后代元素的数目 public int getSize(); // 在孩子发生变化后,更新当前节点及其祖先的规模 public void updateSize(); // 返回当前节点的高度 public int getHeight(); // 在孩子发生变化后,更新当前节点及其祖先的高度 public void updateHeight(); // 返回当前节点的深度 public int getDepth(); // 在父亲发生变化后。更新当前节点及其后代的深度 public void updateDepth(); // 按照中序遍历的次序,找到当前节点的直接前驱 public BinTreePosition getPrev(); // 按照中序遍历的次序,找到当前节点的直接后继 public BinTreePosition getSucc(); // 断绝当前节点与其父亲的父子关系,返回当前节点 public BinTreePosition secede(); // 将节点c作为当前节点的左孩子 public BinTreePosition attachL(BinTreePosition c); // 将节点c作为当前节点的右孩子 public BinTreePosition attachR(BinTreePosition c); // 前序遍历 public MyIterator elementsPreorder(); // 中序遍历 public MyIterator elementsInorder(); // 后序遍历 public MyIterator elementsPostorder(); // 层次遍历 public MyIterator elementsLevelorder(); }
package codes04; /* * 基于链表节点实现二叉树节点 * */ public class BinTreeNode implements BinTreePosition{ // 该节点中存放的对象 protected Object element; // 父亲 protected BinTreePosition parent; // 左孩子 protected BinTreePosition lChild; // 右孩子 protected BinTreePosition rChild; // 后代数目 protected int size; // 高度 protected int height; // 深度 protected int depth; /**************************** 构造方法 ****************************/ public BinTreeNode(){ this(null, null, true, null, null); } public BinTreeNode(Object e, BinTreePosition p, boolean asLChild, BinTreePosition l, BinTreePosition r){ // e:节点内容, p:父节点, asLChild:是否作为父节点的左孩子,l:左孩子, r:右孩子 // 初始化 size = 1; // 深度和高度都是从零开始的 height = depth = 0; // 相当于设置根节点 parent = lChild = rChild = null; // 存放的对象 element = e; // 建立与父亲的关系 // 如果p不为null,则 if (null != p){ // 如果asLChild为true,则将该节点作为p节点的左孩子 if (asLChild) { p.attachL(this); }else{ // 如果asLChild为false,则将该节点作为p节点的右孩子 p.attachR(this); } } // 建立与孩子的关系 if (null != l) { // 如果l不为null,则将l作为该节点的左孩子 attachL(l); } if (null != r){ // 如果r不为null,则将r作为该节点的右孩子 attachR(r); } } /**************************** Position接口方法 ********************************/ // 返回当前节点中存放的对象 public Object getElem(){ return element; } // 将对象obj存入当前节点,并返回此前的内容 public Object setElem(Object obj){ Object bak = element; element = obj; return bak; } /**************************** BinTreePosition接口方法 *************************/ // 判断是否有父亲(为使代码描述简洁) public boolean hasParent(){ return null != parent; } // 返回当前节点的父节点 public BinTreePosition getParent(){ return parent; } // 设置当前节点的父节点 public void setParent(BinTreePosition p){ parent = p; } // 判断是否为叶子 public boolean isLeaf(){ return !hasLChild() && !hasRChild(); } // 判断是否为左孩子 public boolean isLChild(){ // 若当前节点有父亲,而且是左孩子,则返回true;否则,返回false return (hasParent() && this == getParent().getLChild()) ? true : false; } // 判断是否有左孩子 public boolean hasLChild(){ return null != lChild; } // 返回当前节点的左孩子 public BinTreePosition getLChild(){ return lChild; } // 设置当前节点的左孩子(注意:this.lChild和c.parent都不一定为空) public void setLChild(BinTreePosition c){ lChild = c; } // 判断是否为右孩子(为使代码描述简洁) public boolean isRChild(){ // 若当前节点有父亲,而且是右孩子,则返回true;否则,返回false return (hasParent() && this == getParent().getRChild()) ? true : false; } // 判断是否有右孩子(为使代码描述简洁) public boolean hasRChild(){ return null != rChild; } // 返回当前节点的右孩子 public BinTreePosition getRChild(){ return rChild; } // 设置当前节点的右孩子(注意:this.rChild和c.parent都不一定为空) public void setRChild(BinTreePosition c){ rChild = c; } // 返回当前节点后代元素的数目 public int getSize(){ return size; } // 在孩子发生变化后,更新当前节点及其祖先的规模 public void updateSize() { //当前节点 size = 1; if (hasLChild()){ // 左子树的规模 size += getLChild().getSize(); } if (hasRChild()){ // 右子树的规模 size += getRChild().getSize(); } if (hasParent()){ //递归更新各个真祖先的规模记录 getParent().updateSize(); } } // 返回当前节点的高度 public int getHeight(){ return height; } // 在孩子发生变化后,更新当前节点及其祖先的高度 public void updateHeight() { // 先假设没有左、右孩子 height = 0; if (hasLChild()){ // 左孩子的高度 height = Math.max(height, 1+getLChild().getHeight()); } if (hasRChild()){ // 右孩子的高度 height = Math.max(height, 1+getRChild().getHeight()); } if (hasParent()){ // 递归更新各个真祖先的高度记录 getParent().updateHeight(); } } // 返回当前节点的深度 public int getDepth(){ return depth; } // 在父亲发生变化后,更新当前节点及其后代的深度 public void updateDepth() { // 当前节点 depth = hasParent() ? 1 + getParent().getDepth() : 0; if (hasLChild()){ // 沿孩子引用逐层向下, getLChild().updateDepth(); } if (hasRChild()){ // 递归地更新所有后代的深度记录 getRChild().updateDepth(); } } // 按照中序遍历的次序,找到当前节点的直接前驱 public BinTreePosition getPrev(){ // 若左子树非空,则其中的最大者即为当前节点的直接前驱 if (hasLChild()){ return findMaxDescendant(getLChild()); } // 至此,当前节点没有左孩子 if (isRChild()){ // 若当前节点是右孩子,则父亲即为其直接前驱 return getParent(); } //至此,当前节点没有左孩子,而且是左孩子 BinTreePosition v = this; //从当前节点出发 while (v.isLChild()){ // 沿左孩子链一直上升 v = v.getParent(); } // 至此,v或者没有父亲,或者是父亲的右孩子 return v.getParent(); } // 按照中序遍历的次序,找到当前节点的直接后继 public BinTreePosition getSucc() { // 若右子树非空,则其中的最小者即为当前节点的直接后继 if (hasRChild()){ return findMinDescendant(getRChild()); } // 至此,当前节点没有右孩子 if (isLChild()){ // 若当前节点是左孩子,则父亲即为其直接后继 return getParent(); } // 至此,当前节点没有右孩子,而且是右孩子 // 从当前节点出发 BinTreePosition v = this; while (v.isRChild()){ // 沿右孩子链一直上升 v = v.getParent(); } // 至此,v或者没有父亲,或者是父亲的左孩子 return v.getParent(); } // 断绝当前节点与其父亲的父子关系 // 返回当前节点 public BinTreePosition secede() { // 如果有父节点 if (null != parent) { // 当前节点为左孩子 if (isLChild()){ // 切断父亲指向当前节点的引用 parent.setLChild(null); }else{ // 当前节点为右孩子,切断父节点指向当前节点的引用 parent.setRChild(null); } // 更新当前节点及其祖先的规模 parent.updateSize(); // 更新当前节点及其祖先的高度 parent.updateHeight(); // 切断当前节点指向原父亲的引用 parent = null; // 更新节点及其后代节点的深度 updateDepth(); } return this; } // 将节点c作为当前节点的左孩子 public BinTreePosition attachL(BinTreePosition c) { // 如果有左孩子 if (hasLChild()){ // 摘除当前节点原先的左孩子 getLChild().secede(); } if (null != c) { // c脱离原父亲 c.secede(); // 确立新的父子关系 lChild = c; c.setParent(this); //更新当前节点及其祖先的规模 updateSize(); // 更新当前节点及其祖先的高度 updateHeight(); // 更新c及其后代节点的深度 c.updateDepth(); } return this; } //将节点c作为当前节点的右孩子 public BinTreePosition attachR(BinTreePosition c) { // 如果有右孩子 if (hasRChild()){ // 摘除当前节点原先的右孩子 getRChild().secede(); } if (null != c) { // c脱离原父亲 c.secede(); // 确立新的父子关系 rChild = c; c.setParent(this); // 更新当前节点及其祖先的规模 updateSize(); // 更新当前节点及其祖先的高度 updateHeight(); // 更新c及其后代节点的深度 c.updateDepth(); } return this; } // 前序遍历 public MyIterator elementsPreorder() { MyList list = new List_DLNode(); preorder(list, this); // 返回这个列表的元素迭代器 return list.elements(); } // 中序遍历 public MyIterator elementsInorder() { MyList list = new List_DLNode(); inorder(list, this); return list.elements(); } // 后序遍历 public MyIterator elementsPostorder() { MyList list = new List_DLNode(); postorder(list, this); return list.elements(); } // 层次遍历 public MyIterator elementsLevelorder() { MyList list = new List_DLNode(); levelorder(list, this); return list.elements(); } /**************************** 辅助方法 ****************************/ // 在v的后代中,找出最小者 protected static BinTreePosition findMinDescendant(BinTreePosition v) { if (null != v) while (v.hasLChild()){ // 从v出发,沿左孩子链一直下降 v = v.getLChild(); } // 至此,v或者为空,或者没有左孩子 return v; } // 在v的后代中,找出最大者 protected static BinTreePosition findMaxDescendant(BinTreePosition v) { if (null != v) while (v.hasRChild()){ // 从v出发,沿右孩子链一直下降 v = v.getRChild(); } // 至此,v或者为空,或者没有右孩子 return v; } // 前序遍历以v为根节点的(子)树 protected static void preorder(MyList list, BinTreePosition v) { // 递归基:空树 if (null == v) return; // 访问v list.insertLast(v); // 遍历左子树 preorder(list, v.getLChild()); // 遍历右子树 preorder(list, v.getRChild()); } // 中序遍历以v为根节点的(子)树 protected static void inorder(MyList list, BinTreePosition v) { // 递归基:空树 if (null == v) return; // 遍历左子树 inorder(list, v.getLChild()); // 访问v list.insertLast(v); // 遍历右子树 inorder(list, v.getRChild()); } // 后序遍历以v为根节的(子)树 protected static void postorder(MyList list, BinTreePosition v) { // 递归基:空树 if (null == v) return; // 遍历左子树 postorder(list, v.getLChild()); // 遍历右子树 postorder(list, v.getRChild()); // 访问v list.insertLast(v); } //层次遍历以v为根节点的(子)树 protected static void levelorder(MyList list, BinTreePosition v) { // 空队 Queue_List Q = new Queue_List(); // 根节点入队 Q.enqueue(v); // Q不为空 while (!Q.isEmpty()) { // 出队 BinTreePosition u = (BinTreePosition) Q.dequeue(); // 访问v list.insertLast(u); if (u.hasLChild()){ Q.enqueue(u.getLChild()); } if (u.hasRChild()){ Q.enqueue(u.getRChild()); } } } }
package codes04; /* * 基于单链表实现的队列 */ public class Queue_List { protected Node head; protected Node tail; protected int size; public Queue_List(){ head = null; tail = null; size = 0; } public int getSize(){ return size; } public boolean isEmpty(){ return (0 == size) ? true : false; } // 入队 public void enqueue(Object obj){ Node node = new Node(); node.setElem(obj); // 新节点作为尾节点插入 node.setNext(null); if(0 == size){ // 若此前队列为空,直接插入 head = node; }else{ // 将新节点接至队列末端 tail.setNext(node); } // 更新末节点引用 tail = node; size++; } // 出队 public Object dequeue() throws ExceptionQueueEmpty{ if(0 == size){ throw new ExceptionQueueEmpty("意外:队列为空"); } Object obj = head.getElem(); head = head.getNext(); size--; if(0 == size){ tail = null; } return obj; } // 取并不删除队首元素 public Object first() throws ExceptionQueueEmpty{ if(isEmpty()){ throw new ExceptionQueueEmpty("队列为空"); } return head.getElem(); } // 遍历 public void traversal(){ Node p = head; while(p != null){ System.out.println(p.getElem() + " "); p = p.getNext(); } } }
相关文章推荐
- MySQL入门
- Navicat 8 for mysql 连接远程mysql
- 03-树2 List Leaves
- 日志记录和缺陷记录
- 第三周pspo过程文档
- LeetCode[3] Longest Substring Without Repeating Characters
- mybatis分页插件的简单实现
- Gson 常见json对象的解析
- 你就可以在这项计划中
- JavaWeb开发之十三:Javabean
- 编码规范的作用
- Java中@Override的作用
- 单链表建环
- C#中服务端接受前端JSON字符串转换成字典集合
- Leetcode 第一题 Two Sum java代码
- Java面对对象入门
- 四则运算第三版
- sscanf函数
- linux内核的组成,王明学learn
- 学习进度03