关于树的一些总结
2015-07-25 18:10
267 查看
最近学习java的相关内容,涉及到数据结构中树的一些操作,先总结一下,以后慢慢完善
树的主要操作有:
基本操作(添加,删除,查找一个结点)
遍历(前序,中序,后序,层序)
创建一颗树(根据前序遍历的格式;根据前序和中序遍历);销毁树
判断一颗树是否平衡;判断两棵树是否相等
获取树的高度和宽度
.等等。。。
代码如下:
说明:有的代码是参考c实现的,java和c在实现上确实有很多不同的地方,尤其是树的递归调用,java中不能引用基本变量,只能是对象,所以在实现上与c相比,不太方便
树的其他操作以后遇到再慢慢补上。。。。
树的主要操作有:
基本操作(添加,删除,查找一个结点)
遍历(前序,中序,后序,层序)
创建一颗树(根据前序遍历的格式;根据前序和中序遍历);销毁树
判断一颗树是否平衡;判断两棵树是否相等
获取树的高度和宽度
.等等。。。
代码如下:
/*定义树的结点*/ class BTNode{ char data; BTNode leftNode; BTNode rightNode; public BTNode(){} public BTNode(char data) { this.data = data; } } /** * 定义树的数据结构 */ public class BTree{ private BTNode root; public BTree() {} /*初始化根节点*/ public BTree(char rootData) { this.root = new BTNode(rootData); } /*根据前序遍历创建树*/ public BTree(char[] arr){ this.arr = arr; this.root = createTree(); } //使用递归,查找一个结点 public BTNode search(BTNode root, char data){ BTNode temp = null; if(root != null){ if (root.data == data) { return root; }else { temp = search(root.leftNode, data); if(temp == null) return search(root.rightNode, data); } } return temp; } //在指定的结点上增加一个结点,type为0时添加左结点,为1时添加右结点 public void add(char parentData, char data, int type){ BTNode node = new BTNode(),tempNode; //找到parentData的结点 tempNode = search(root, parentData); if(tempNode != null){ node.data = data; if (type == 0) tempNode.leftNode = node; if (type == 1) tempNode.rightNode = node; }else { System.out.println("找不到指定的结点!"); } } /** * 清除树 * @param root */ public void clear(BTNode root){ if (root != null) { clear(root.leftNode); clear(root.rightNode); root = null; } } /** * 层序遍历 * @param root */ private void levelInner(BTNode root){ //定义队列来存储各层的结点,maxlen各层最大结点数 BTNode[] temp = new BTNode[MAXLEN]; int head = 0, tail = 0; BTNode t; //入队 if (root != null ) { tail = (tail + 1) % MAXLEN; temp[tail] = root; } while(head != tail){ //处理结点 head = (head +1) % MAXLEN; t = temp[head]; System.out.println("处理结点数据"+ t.data); //添加结点 if (t.leftNode != null) { temp[++tail % MAXLEN] = t.leftNode; } if (t.rightNode != null) { temp[++ tail % MAXLEN] = t.rightNode; } } } //包装一下 public void levelOrder(){ levelInner(this.root); } /** * 前序遍历 * @param root */ private void dlrInner(BTNode root){ if (root != null) { System.out.println(root.data); dlrInner(root.leftNode); dlrInner(root.rightNode); } } public void preOrder(){ dlrInner(this.root); } /** * 中序遍历 * @param root */ private void ldrInner(BTNode root){ if (root != null) { ldrInner(root.leftNode); System.out.println(root.data); ldrInner(root.rightNode); } } public void inOrder(){ ldrInner(this.root); } /** * 后序遍历 * @param root */ private void ltdInner(BTNode root){ if (root != null) { ltdInner(root.leftNode); ltdInner(root.rightNode); System.out.println(root.data); } } public void postOrder(){ ltdInner(this.root); } /*根据前序遍历格式创建一个树 1 2 4 6 0 0 7 0 0 5 8 0 0 9 0 0 3 0 0 要使用两个成员变量,如果用c实现更方便,可以传入指针创建*/ private char[] arr; private int i; private BTNode createTree(){ BTNode node = null; if(i>=arr.length||arr[i] ==0){ i++; return null; }else{ node = new BTNode(arr[i++]); node.leftNode = createTree(); node.rightNode = createTree(); } return node; } //根据前序遍历和中序遍历创建一棵树,定义成静态类 private static BTNode createTreeInner(String preOrder,String inOrder, int len) throws Exception{ if(preOrder == null&& inOrder== null) return null; BTNode node = new BTNode(preOrder.charAt(0)); //在中序遍历中寻找根结点 int i =0; while(preOrder.charAt(0)!=inOrder.charAt(i)){ i++; if(i>=len) throw new Exception("Error"); } //创建左子树 if(i>0) node.leftNode = createTreeInner(preOrder.substring(1), inOrder, i); //创建右子树 if(i<len-1) node.rightNode = createTreeInner(preOrder.substring(i+1), inOrder.substring(i+1), len-i-1); return node; } public static BTree createTree(String preOrder,String inOrder) throws Exception{ BTree btree = new BTree(); btree.setRoot(createTreeInner(preOrder, inOrder, inOrder.length())); return btree; } /** * 获取树的宽度 * @param root * @return */ public int getWidth(BTNode root){ int currentCount = 1,count=0; BTNode temp; LinkedList<BTNode> ll = new LinkedList<BTNode>(); ll.offer(root); while(currentCount!=0){ while(currentCount!=0){ temp = ll.poll(); if(temp.leftNode!=null){ ll.offer(temp.leftNode); } if(temp.rightNode != null){ ll.offer(temp.rightNode); } currentCount--; } currentCount = ll.size(); //保存最多的结点 if(currentCount>count) count = currentCount; } return count; } /** * 判断两棵树是否相同 * @param a * @param b * @return */ private boolean equalInner(BTNode a, BTNode b){ if(a==null&&b!=null||a!=null&&b==null) return false; else if(a!=null&&b!=null){ if(a.data != b.data){ return false; }else if(!equalInner(a.leftNode, b.leftNode)){ return false; }else if(!equalInner(a.rightNode, b.rightNode)){ return false; } } return true; } public boolean equals(BTree tree){ if(equalInner(root, tree.getRoot())){ return true; } return false; } /** * 获取树的深度 * @param root * @return */ public int getDeep(BTNode root){ int deepleft ,deepright; if (root == null) { return 0; } deepleft = getDeep(root.leftNode); deepright = getDeep(root.rightNode); if (deepleft >= deepright) { return ++deepleft; }else{ return ++deepright; } } /** * 判断树是否是平衡树 * @param root * @return */ //方法一:先获取树的高度,然后才判断,由高到底(效率不高,java可方便实现) private boolean isBalanceInner(BTNode root){ if(root == null){ return true; } int leftHeight = getDeep(root.leftNode); int rightHeight = getDeep(root.rightNode); int diff = leftHeight - rightHeight; if(diff>1||diff<-1){ return false; } return isBalanceInner(root.leftNode)&&isBalanceInner(root.rightNode); } //包装一下 public boolean isBalance(){ return isBalanceInner(this.root); } //方法二:利用后序遍历的特征,一次性获取,由低到高 //需要定义一个辅助类 private class Depth { int height; } private boolean isBalanceInner(BTNode node,Depth d){ if(node==null){ d.height=0; return true; } Depth right=new Depth(); Depth left = new Depth(); if(isBalanceInner(node.leftNode,left)&&isBalanceInner(node.rightNode,right)){ int diff = left.height-right.height; if(diff<=1||diff>=-1){//绝对值小于等于1 //如果是平衡树,才有必要算深度,然后看上级是不是平衡树 d.height=left.height>right.height?left.height:right.height; return true; } } return false; } //包装一下 public boolean isBalance2(BTNode root){ return isBalanceInner(root,new Depth()); } public BTNode getRoot(){ return this.root; } public void setRoot(BTNode root){ this.root = root; } }
说明:有的代码是参考c实现的,java和c在实现上确实有很多不同的地方,尤其是树的递归调用,java中不能引用基本变量,只能是对象,所以在实现上与c相比,不太方便
树的其他操作以后遇到再慢慢补上。。。。
相关文章推荐
- Android 01:AutoCompleteTextView-简单实现实现自动输入文本效果
- SHU_OJ 1929:Yaoge的英语成绩题解
- CocoaPods 安装及基本使用方法
- grep用法小结
- Vs2012 构建配置 Lua5.2.3
- 深入分析ConcurrentHashMap(转)
- java bean对象之间复制属性
- 数据库中的左连接(left join)和右连接(right join)区别
- 阿里电话面试题详解
- JSLink文件中使用field的自定义属性
- poj3169 差分约束系统
- 输出一个等边三角形的字母阵,等边三角形的两腰为字母A,往里靠依次字母大一个(详细题目文章中描述)
- 输出一个等边三角形的字母阵,等边三角形的两腰为字母A,往里靠依次字母大一个(详细题目文章中描述)
- 二分搜索 Codeforces Round #218 (Div. 2) C. Hamburgers
- javascript实现动态导入js与css等静态资源文件的方法
- C++ 继承与接口 知识点 小结(一)
- HDU1312 Red and Black 解读
- 我关注的一周技术动态2015.7.26
- DNA Sorting(排序)
- MD5Util