关于树的一些总结
来源:互联网 发布:数组 reverse 编辑:程序博客网 时间:2024/04/29 20:19
最近学习java的相关内容,涉及到数据结构中树的一些操作,先总结一下,以后慢慢完善
树的主要操作有:
- 基本操作(添加,删除,查找一个结点)
- 遍历(前序,中序,后序,层序)
- 创建一颗树(根据前序遍历的格式;根据前序和中序遍历);销毁树
- 判断一颗树是否平衡;判断两棵树是否相等
- 获取树的高度和宽度
- .等等。。。
/*定义树的结点*/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;}}
树的其他操作以后遇到再慢慢补上。。。。
0 0
- 关于树的一些总结
- 关于数据结构之树的一些总结
- 关于继承的一些总结
- 关于Cache的一些总结
- 关于触摸屏的一些总结
- 关于乱码的一些总结
- 关于SOCKET的一些总结
- 关于工作的一些总结
- 关于C++的一些总结
- 关于文件的一些总结
- 关于DOM的一些总结
- 关于数据库的一些总结
- 关于一些问题的总结
- 关于cgi的一些总结
- 关于ListActivity的一些总结
- 关于NEON的一些总结
- 关于stringstream的一些总结
- 关于OProfile的一些总结
- 黑马程序员——练习题:向一维数组输入元素并全部输出
- JavaScript的执行上下文
- POM.xml详解
- JavaScript内存泄漏
- linux系统编程:线程同步-读写锁(rwlock)
- 关于树的一些总结
- Common Subsequence-最长公共子序列
- input文本框输入禁止的不同方式
- java多线程学习笔记——读写锁(ReentrantReadWriteLock)
- centos 7 gerrit安装配置
- 如何在一个页面上让多个jQuery版本共存
- Java学习笔记-------Java引出GUI组件的事件 ???
- SwipeRefreshLayout使用心得
- iOS UIFont 字体大全