关于树的一些总结

来源:互联网 发布:数组 reverse 编辑:程序博客网 时间:2024/04/29 20:19

最近学习java的相关内容,涉及到数据结构中树的一些操作,先总结一下,以后慢慢完善

树的主要操作有:

  1. 基本操作(添加,删除,查找一个结点)
  2. 遍历(前序,中序,后序,层序)
  3. 创建一颗树(根据前序遍历的格式;根据前序和中序遍历);销毁树
  4. 判断一颗树是否平衡;判断两棵树是否相等
  5. 获取树的高度和宽度
  6. .等等。。。
代码如下:

/*定义树的结点*/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相比,不太方便


树的其他操作以后遇到再慢慢补上。。。。

0 0
原创粉丝点击