看了一下树的定义,一些基本的操作,遍历,获取节点数,获取深度等等。。这里参考了西电版的数据结构,基本用的都是递归实现的。
很多说明代码中都有,每个方法我都测了一下,这里我把节点类BTreeNode作为内部类放到了BTree中,方便一下。其实可以拿出来。还有我用的是二叉链表实现的树的存储,因为java 不能将函数(方法)作为参数传递,所以将visit()方法封装到了Visit类中,将Visit类对象作为参数传递
BTree.java
1 package com.gxf.tree; 2 3 /** 4 * 定义数的属性和一些基本操作 5 * @author Administrator 6 * 7 */ 8 public class BTree { 9 /** 10 * 树节点类 11 * 这里用二叉链表,存储 12 * @author Administrator 13 * 14 */ 15 class BTreeNode{ 16 private Object data; 17 private BTreeNode lchild; 18 private BTreeNode rchild; 19 20 public BTreeNode(){ 21 lchild = null; 22 rchild = null; 23 } 24 public void setData(Object data){ 25 this.data = data; 26 } 27 public void setLchild(BTreeNode lchild){ 28 this.lchild = lchild; 29 } 30 public void setRchild(BTreeNode rchild){ 31 this.rchild = rchild; 32 } 33 public Object getData(){ 34 return data; 35 } 36 } 37 //下面是二叉树的一些属性 38 private Object array[];//用数组保存所有树节点的数据 39 private BTreeNode root;//根节点 40 private Visit visit = new Visit();//java 不能将函数作为函数的参数,用一个类封装方法 41 42 /** 43 * 构造一棵树,指向根节点 44 * @param array 45 */ 46 public BTree(Object array[]){ 47 this.array = array; 48 root = build(1); 49 } 50 51 /** 52 * 根据成员变量array[]递归构造一棵树 53 * 构造左子树、右子树 54 * @return 55 */ 56 public BTreeNode build(int i){ 57 int n = array.length; 58 59 if(i <= n){//i在数组内,说明可以构造一个以array[i]为根节点的子树 60 BTreeNode treeNode = new BTreeNode(); 61 treeNode.setData(array[i - 1]);//设置根节点 62 treeNode.setLchild(build(2 * i));//构造左子树 63 treeNode.setRchild(build(2 * i + 1));//构造右子树 64 65 return treeNode; 66 }else{ 67 return null; 68 } 69 } 70 /** 71 * 获取树的所有节点的个数 72 */ 73 public int getNodeNum(){ 74 return getNodeNum(root); 75 } 76 /** 77 * 计算所有节点的个数 78 * 递归实现,左子树个数 + 右子树个数 + 1 79 * @param root 80 * @return 81 */ 82 public int getNodeNum(BTreeNode root){ 83 if(null == root) 84 return 0; 85 else 86 { 87 return getNodeNum(root.lchild) + getNodeNum(root.rchild) + 1; 88 } 89 90 } 91 /** 92 * 获取树的高度 93 * @return 94 */ 95 public int getDep(){ 96 return getDep(root); 97 } 98 /** 99 * 获取树的高度 100 * 递归获取左右子树的高度,返回最高的那个 101 * root为空,返回0,说明为空树,高度为0 102 * 如果不为空,左子树和右子树高度较大值 +1为树的高度 103 * @param root 104 * @return 105 */ 106 public int getDep(BTreeNode root){ 107 if(null == root) 108 return 0;//空树返回0,高度为0,也是函数的出口 109 else{ 110 int max = getDep(root.lchild);//获取左子树的高度 111 if(max < getDep(root.rchild)) 112 max = getDep(root.rchild);//获取右子树高度,并和左子树比较 113 114 return max + 1;//因为不为空树,树的高度为左右子树高度的最大值 + 1 115 } 116 117 } 118 /** 119 * 前序遍历 120 */ 121 public void preOrder(){ 122 preOrder(root); 123 } 124 /** 125 * 前序遍历树,先遍历根节点,在遍历左节点,右节点 126 * 127 * @param root 128 */ 129 public void preOrder(BTreeNode root){ 130 if(null != root){ 131 visit.visit(root); 132 preOrder(root.lchild); 133 preOrder(root.rchild); 134 } 135 } 136 /** 137 * 中序遍历 138 */ 139 public void inOrder(){ 140 inOrder(root); 141 } 142 /** 143 * 中序遍历,县遍历左子树,根,最后遍历右子树 144 * 递归实现 145 * @param root 146 */ 147 public void inOrder(BTreeNode root){ 148 if(null != root) 149 { 150 inOrder(root.lchild); 151 visit.visit(root); 152 inOrder(root.rchild); 153 } 154 } 155 /** 156 * 后序遍历 157 */ 158 public void postOrder(){ 159 postOrder(root); 160 } 161 /** 162 * 后序遍历,先遍历左子树,右子树和根节点 163 * 这也用递归实现 164 * @param root 165 */ 166 public void postOrder(BTreeNode root){ 167 if(null != root){//这里可以看成递归的出口 168 postOrder(root.lchild); 169 postOrder(root.rchild); 170 visit.visit(root); 171 } 172 } 173 174 }
Visit.java
1 package com.gxf.tree; 2 3 import com.gxf.tree.BTree.BTreeNode; 4 5 6 public class Visit { 7 public void visit(BTreeNode node){ 8 System.out.print(node.getData() + " "); 9 } 10 public void printLine(){ 11 System.out.println(); 12 } 13 }
Test.java
1 package com.gxf.tree; 2 3 public class Test { 4 5 public static void main(String[] args) { 6 Visit visit = new Visit(); 7 8 Character array_ch[] = new Character[]{'-', '*', 'c', 'a', 'b'}; 9 BTree tree = new BTree(array_ch); 10 //前序、中序和后序遍历 11 tree.preOrder(); 12 visit.printLine(); 13 tree.inOrder(); 14 visit.printLine(); 15 tree.postOrder(); 16 visit.printLine(); 17 //获取节点数和树的深度 18 System.out.println(tree.getNodeNum()); 19 System.out.println(tree.getDep()); 20 } 21 22 }
测试输出