使用java实现链式存储的二叉树
来源:互联网 发布:mac版阿里旺旺打不开 编辑:程序博客网 时间:2024/06/17 06:19
上一篇文章写了使用java实现顺序存储的二叉树,这次接着使用java实现链式存储的二叉树:
首先创建一个结点类TreeNode<E>:
package com.linkedTree;public class TreeNode<E> { private E item; private TreeNode<E> leftChild; private TreeNode<E> rightChild; public TreeNode(E item){ this(item,null,null); } public TreeNode(E item, TreeNode<E> l , TreeNode<E> r){ this.item = item; this.leftChild = l; this.rightChild = r; } public TreeNode<E> getRightChild() { return rightChild; } public void setRightSibling(TreeNode<E> rightChild) { this.rightChild = rightChild; } public TreeNode<E> getLeftChild() { return leftChild; } public void setLeftSibling(TreeNode<E> leftChild) { this.leftChild = leftChild; } public E getItem() { return item; } public void setItem(E item) { this.item = item; } @Override public int hashCode() {//重写hashCode和equals方法 final int prime = 31; int result = 1; result = prime * result + ((item == null) ? 0 : item.hashCode()); result = prime * result + ((leftChild == null) ? 0 : leftChild.hashCode()); result = prime * result + ((rightChild == null) ? 0 : rightChild.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; TreeNode<?> other = (TreeNode<?>) obj; if (item == null) { if (other.item != null) return false; } else if (!item.equals(other.item)) return false; if (leftChild == null) { if (other.leftChild != null) return false; } else if (!leftChild.equals(other.leftChild)) return false; if (rightChild == null) { if (other.rightChild != null) return false; } else if (!rightChild.equals(other.rightChild)) return false; return true; } }
然后创建一个接口LTree<E>,规范链式存储二叉树的方法:
package com.linkedTree;import com.linkedTree.TreeNode;public interface Ltree<E> { boolean isEmpty(); TreeNode<E> getRoot(); TreeNode<E> getParent(TreeNode<E> node); TreeNode<E> getLeftChild(TreeNode<E> node); TreeNode<E> getRightChild(TreeNode<E> node); void breadFirstOrder();//广度优先 void preOrder();//先序遍历 void inOrder();//中序遍历 void postOrder();//后序遍历 void clear();//删除整个树}
接着创建一个类LinkedTree<E>来实现LTree<E>接口:
package com.linkedTree;import java.util.HashSet;import java.util.LinkedList;import java.util.Queue;import java.util.Set;import java.util.Stack;public class LinkedTree<E> implements Ltree<E> { private TreeNode<E> root; public LinkedTree(TreeNode<E> root){ this.root = root; } @Override public boolean isEmpty() { return root == null; } @Override public TreeNode<E> getRoot() { return root; } @Override public TreeNode<E> getParent(TreeNode<E> node) { /** * 采用后序遍历来寻找其父节点 * 后序遍历: * 从根结点开始,向左搜索,每搜索到一个结点就将其压入栈中,直到压入栈中的结点不再有左子树。读取栈顶元素,如果结点有右子树不为空且未被访问则入栈当前结点访问其右子树,否则访问当前元素弹栈访问 * */ Stack<TreeNode<E>> nodeStack = new Stack<TreeNode<E>>(); TreeNode<E> pointer = root; Set<TreeNode<E>> visitedSet = new HashSet<TreeNode<E>>(); while(pointer != null){ while(pointer.getLeftChild()!=null){ nodeStack.push(pointer); pointer = pointer.getLeftChild(); } while( pointer != null&& (pointer.getRightChild()==null||visitedSet.contains(pointer.getRightChild()))){ if(node.equals(pointer)) return nodeStack.pop(); visitedSet.add(pointer); if(nodeStack.isEmpty()) return null; pointer = nodeStack.pop(); } nodeStack.push(pointer); pointer = pointer.getRightChild(); } return null; } @Override public TreeNode<E> getLeftChild(TreeNode<E> node) { return node.getLeftChild(); } @Override public TreeNode<E> getRightChild(TreeNode<E> node) { return node.getRightChild(); } @Override public void breadFirstOrder() { /** * 广度优先遍历: * 用队列来实现,对于根节点,进行访问,然后出队列将左孩子放入队列如果不为空,右孩子放入队列如果不为空, * 然后继续分别访问左孩子,将左孩子的左孩子右孩子放入队列,同理右孩子,以此类推,直到队列为空 * */ String str = ""; Queue<TreeNode<E>> nodeList =new LinkedList<TreeNode<E>>();//LinkedLits实现了Queue而ArrayList没有实现 因此前者可以当队列用 后者不可以 nodeList.add(root); while(!nodeList.isEmpty()){ TreeNode<E> node = nodeList.poll(); str+=node.getItem()+" "; if(node.getLeftChild()!=null){ nodeList.add(node.getLeftChild()); } if(node.getRightChild()!=null){ nodeList.add(node.getRightChild()); } } System.out.println(str); } @Override public void preOrder() { /** * 先序遍历: * 访问一个节点,然后遍历访问左子树,将右子树压入栈中,依次弹栈 直到栈空 * */ Stack<TreeNode<E>> nodeStack = new Stack<TreeNode<E>>(); TreeNode<E> pointer = root; String str = ""; while(!nodeStack.isEmpty()||pointer!=null){ if(pointer!=null){ str += pointer.getItem()+" "; TreeNode<E> l = pointer.getLeftChild(); TreeNode<E> r = pointer.getRightChild(); pointer = l; if(r!=null){ nodeStack.push(r); } } else{ pointer = nodeStack.pop(); } } System.out.println(str); } @Override public void inOrder() { /** * 中序遍历: * 从根节点开始,对左子树进行遍历,将遍历到的左子树压入栈中,遍历完后访问弹栈的结点,访问该节点的右子树,同理前面的方法继续遍历右子树的左子树 直到栈空 * */ Stack<TreeNode<E>> nodeStack = new Stack<TreeNode<E>>(); String str = ""; TreeNode<E> pointer = root; while(!nodeStack.isEmpty()||pointer!=null){ if(pointer!=null){//将左子树一一放入栈 nodeStack.push(pointer); pointer = pointer.getLeftChild(); } else{//当前结点没有左子树了 pointer = nodeStack.pop(); str += pointer.getItem()+" "; pointer = pointer.getRightChild(); } } System.out.println(str); } @Override public void postOrder() { /** * 后序遍历: * 从根结点开始,向左搜索,每搜索到一个结点就将其压入栈中,直到压入栈中的结点不再有左子树。读取栈顶元素,如果结点右右子树不为空且未被访问则当前结点入栈,访问其右子树,否则访问当前元素 弹栈 * */ Stack<TreeNode<E>> nodeStack = new Stack<TreeNode<E>>(); TreeNode<E> pointer = root; Set<TreeNode<E>> visitedSet = new HashSet<TreeNode<E>>();//存放被访问过的元素 String str = ""; while(pointer!=null){ for(;pointer.getLeftChild()!=null;pointer = pointer.getLeftChild()){//最后一个有左子树的结点的左子树没有被压入栈 nodeStack.push(pointer);//将所有左子树结点压入栈中 } while(pointer!=null && (pointer.getRightChild()==null||visitedSet.contains(pointer.getRightChild()))){//右子树被访问过了或者右子树为空 str += pointer.getItem()+" "; visitedSet.add(pointer);//把pointer置为被访问了 if(nodeStack.isEmpty()) { System.out.println(str); return; } pointer = nodeStack.pop(); } nodeStack.push(pointer); pointer = pointer.getRightChild(); } } @Override public void clear() { root = null;//直接root=null就可以 因为剩下的结点会因为不可达而被GC回收 }}
最后写测试类,来进行测试:
public class Test{ public static void main(String[] args) {System.out.println("LinkedTree test:"); TreeNode<Integer> node7 = new TreeNode<Integer>(7); TreeNode<Integer> node8 = new TreeNode<Integer>(8); TreeNode<Integer> node3 = new TreeNode<Integer>(3,node7,node8); TreeNode<Integer> node4 = new TreeNode<Integer>(4); TreeNode<Integer> node5 = new TreeNode<Integer>(5); TreeNode<Integer> node6 = new TreeNode<Integer>(6); TreeNode<Integer> node2 = new TreeNode<Integer>(2,node5,node6); TreeNode<Integer> node1 = new TreeNode<Integer>(1,node3,node4); TreeNode<Integer> root = new TreeNode<Integer>(0, node1, node2); LinkedTree<Integer> lt = new LinkedTree<Integer>(root); lt.breadFirstOrder();//0 1 2 3 4 5 6 7 8 lt.preOrder();//0 1 3 7 8 4 2 5 6 lt.inOrder();//7 3 8 1 4 0 5 2 6 lt.postOrder();//7 8 3 4 1 5 6 2 0 System.out.println(lt.getParent(node7).getItem());//3 lt.clear(); System.out.println(lt.getRoot());//null }}简单的链式存储二叉树便实现了。
阅读全文
1 0
- 使用java实现链式存储的二叉树
- 二叉树链式存储的实现
- 二叉树链式存储的实现
- 数据结构:二叉树的链式存储实现
- 二叉树链式存储的C实现
- 二叉树的链式存储实现
- 二叉树的链式存储实现
- Java二叉树的实现(链式实现)
- 二叉树的顺序存储和链式存储结构(java实现)
- 二叉树的链式存储
- 二叉树的链式存储
- 二叉树的链式存储
- 二叉树的链式存储
- 二叉树的链式存储
- 二叉树的链式存储
- 二叉树的链式存储
- 二叉树的链式存储
- 数据结构(java语言描述)-- 二叉查找树的链式存储结构的实现
- java发送HTTP和HTTPS请求
- 这可能是最受硅谷欢迎的中国手机
- 机器学习-分类与回归决策树详解ID3,C4.5,CART,Python实现
- Linuxs查看进程,杀死进程
- 修改文件夹名称隐藏文件夹_电脑中的上帝模式
- 使用java实现链式存储的二叉树
- 什么叫工作波长,截止波长和波导波长
- 【转】Docker 运行时资源限制-内存memory、交换机分区Swap、CPU
- 通向全球市场的大门:由Cointelegraph主办的BlockShow将于11月开幕
- 关于“1”像素问题
- qt sprintf()和arg()
- JDK-jinfo:java配置信息工具
- dubbo架构图–从启动日志里看
- 性能测试监控:Jmeter+Collectd+Influxdb+Grafana