1 packagetree;2
3 importjava.util.ArrayDeque;4 importjava.util.ArrayList;5 importjava.util.List;6 importjava.util.Queue;7
8 public class BinaryTree{9 //为什么要用静态内部类?静态内部类中不能访问外部类的非静态成员
10 public static classTreeNode{11 //E data;
12 Object data;13 TreeNode left;14 TreeNode right;15 publicTreeNode(){16
17 }18 publicTreeNode(Object data){19 this.data =data;20 }21 //构造一个新节点,该节点以left节点为其左孩子,right节点为其右孩子
22 publicTreeNode(Object data, TreeNode left, TreeNode right){23 this.data =data;24 this.left =left;25 this.right =right;26 }27 }28
29 private TreeNode root;//实现二叉树的类的数据域,即根结点来表示二叉树
30
31 publicBinaryTree(){32 this.root = newTreeNode();33 }34 //以指定的根元素创建一颗二叉树
35 publicBinaryTree(E data){36 this.root = newTreeNode(data);37 }38
39 //为指定的结点添加子结点,为什么要有addNode方法?因为给定一系列的结点,通过调用该方法来构造成一颗树
40 public TreeNode addNode(TreeNode parent, E data, booleanisLeft){41 if(parent == null)42 throw new RuntimeException("父节点为空,无法添加子结点");43 if(isLeft && parent.left != null)44 throw new RuntimeException("节点已经左子节点,添加失败");45 if(!isLeft && parent.right != null)46 throw new RuntimeException("节点已经有右子节点,添加失败");47 TreeNode newNode = newTreeNode(data);48 if(isLeft)49 parent.left =newNode;50 else
51 parent.right =newNode;52 returnnewNode;53 }54
55 public booleanempty(){56 return root.data == null;//根据根元素判断二叉树是否为空
57 }58
59 publicTreeNode root(){60 if(empty())61 throw new RuntimeException("树空,无法访问根结点");62 returnroot;63 }64
65 publicE parent(TreeNode node){66 return null;//采用二叉树链表存储时,访问父结点需要遍历整棵二叉树,因为这里不实现
67 }68
69 //访问指定节点的左结点,返回的是其左孩子的数据域
70 publicE leftChild(TreeNode parent){71 if(parent == null)72 throw new RuntimeException("空结点不能访问其左孩子");73 return parent.left == null ? null: (E)parent.left.data;74 }75 publicE rightChild(TreeNode parent){76 if(parent == null)77 throw new RuntimeException("空结点不能访问其右孩子");78 return parent.right == null ? null: (E)parent.right.data;79 }80
81 public intdeep(){82 returndeep(root);83 }84 private intdeep(TreeNode node){85 if(node == null)86 return 0;87 else if(node.left == null && node.right == null)88 return 1;89 else{90 int leftDeep =deep(node.left);91 int rightDeep =deep(node.right);92 int max = leftDeep > rightDeep ?leftDeep : rightDeep;93 return max + 1;94 }95 }96
97 /*二叉树的先序遍历,实现思想如下:树是一种非线性结构,树中各个结点的组织方式有多种方式98 * 先序,即是一种组织方式。它将结点的非线性变成了按照某种方式组织成的线性结构99 */
100 //返回一个list,树中结点以先序的方式存放在该list中
101 public ListpreTraverse(){102 returnpreOrderTraverse(root);103 }104 private ListpreOrderTraverse(TreeNode node){105 List list = new ArrayList();106 list.add(node);107 if(node.left != null)108 list.addAll(preOrderTraverse(node.left));//递归的奇妙之处
109 if(node.right != null)110 list.addAll(preOrderTraverse(node.right));111 returnlist;112 }113
114 //中序遍历
115 public ListinTraverse(){116 returninOrderTraverse(root);117 }118 private ListinOrderTraverse(TreeNode node){119 List list = new ArrayList();120 if(node.left != null)121 list.addAll(inOrderTraverse(node.left));122 list.add(node);123 if(node.right != null)124 list.addAll(inOrderTraverse(node.right));125 returnlist;126 }127
128 //后序遍历
129 public ListpostTraverse(){130 returnpost_Traverse(root);131 }132 private Listpost_Traverse(TreeNode node){133 List list = new ArrayList();134 if(node.left != null)135 list.addAll(post_Traverse(node.left));136 if(node.right != null)137 list.addAll(post_Traverse(node.right));138 list.add(node);139 returnlist;140 }141
142 //层序遍历
143 public ListlevelTraverse(){144 returnlevel_Traverse(root);145 }146 private Listlevel_Traverse(TreeNode node){147 Queue queue = new ArrayDeque();148 List list = new ArrayList();//按层序遍历定义的顺序将树中结点依次添加到数组列表中149 if(root != null)//先将根结点入队列150 queue.offer(root);151 while(!queue.isEmpty())//队列不空时,说明遍历还未结束152 {153 list.add(queue.peek());//将队头元素添加到数组列表中154 TreeNode p =queue.poll();//队头元素出队列155 if(p.left != null)156 queue.offer(p.left);//队头元素的左孩子入队列157 if(p.right != null)158 queue.offer(p.right);//队头元素的右孩子入队列159 }160 returnlist;161 }162 }