给你一颗二叉树,然后让你用代码实现创建的过程,紧接着用代码实现它的前序,中序,后序遍历。
例如给妮这样一颗二叉树
代码如下(注释很清楚)
package jzoffer; /* *二叉树链式存储 *@author LSM */ public class Tree { private TreeNoder root = null; //先定义一个根节点 public Tree() { root = new TreeNoder(1, "rootNode(A)"); //在初始化的时候吧根节点初始化为A key当然赋值为1 } /** * 创建一棵二叉树 * <pre> * A * B C * D E F * </pre> * @param root * @author LSM */ public void createTree(TreeNoder treeNoder){ //参数主要就是为了给根节点加节点 TreeNoder treeNoderB = new TreeNoder(2, "B"); //看上面的图 TreeNoder treeNoderC = new TreeNoder(3, "C"); TreeNoder treeNoderD = new TreeNoder(4, "D"); TreeNoder treeNoderE = new TreeNoder(5, "E"); TreeNoder treeNoderF = new TreeNoder(6, "F"); treeNoder.leftChild = treeNoderB; treeNoder.rightChild = treeNoderC; treeNoder.leftChild.leftChild = treeNoderD; treeNoder.rightChild.rightChild = treeNoderF; treeNoder.leftChild.rightChild = treeNoderE; //这样真的好麻烦这就算完成了 } public boolean isEmpty() { //这个就是判断根节点是否为null return root==null; } public int height(){ //主要为了后边调用方便 再不用写root了 return height(root); } public int height(TreeNoder treeNoderHeight){ //这里也是递归的方法 if(treeNoderHeight == null){ return 0; //空树的高度为0 }else{ int i = height(treeNoderHeight.leftChild); int j = height(treeNoderHeight.rightChild); return (i<j)?(j+1):(i+1); //仔细揣摩下这句话的意思 } } //主要为了后边调用方便 再不用写root了 public int size(){ return size(root); } public int size(TreeNoder treeNoderSize){ if(treeNoderSize == null){ return 0; }else{ return 1+size(treeNoderSize.leftChild)+size(treeNoderSize.rightChild); //叶子节点都是0 再加上自身 自己揣摩 } } public TreeNoder parent(TreeNoder treeNoderParent){ if(treeNoderParent == null){ return null; } //这个方法和下面的方法是连着的,只不过为了更方便吧 //其实完全可以只用写下面一个方法,但是如果只写下面一个方法时候 //你每次的参数就必须写一个root 这就很烦了 return (root == null || root == treeNoderParent)?null:parent(root, treeNoderParent); } public TreeNoder parent(TreeNoder treeNoderParent,TreeNoder treeNoderSize){ if(treeNoderParent == null){ //上面也有可能有一种情况就是 根节点root本身就为空那 那我们肯定就自己返回了 return null; } if(treeNoderParent.leftChild == treeNoderSize ||treeNoderParent.rightChild == treeNoderSize){ return treeNoderSize;//如果的根节点的左边的孩子和右边的孩子的话,那么这个节点的双亲节点肯定就是根节点。 } TreeNoder treeNoderP; //递归在左子树中查找 if((treeNoderP = parent(treeNoderParent.leftChild, treeNoderSize))!= null){ //判断左子树 return treeNoderP; }else{ //递归在右子树中查找 return parent(treeNoderParent.rightChild, treeNoderSize); } } //得到一个节点的左孩子节点 public TreeNoder getLeftChildNode(TreeNoder leftChildNode){ return (leftChildNode!=null)?leftChildNode.leftChild:null; } //得到一个节点的右孩子节点 public TreeNoder getRightChildNode(TreeNoder RightChildNode){ return (RightChildNode!=null)?RightChildNode.rightChild:null; } public TreeNoder getRoot(){ return root; } //在释放某个节点的时候,该节点的左右子树都已经释放 //所以应该采用后续遍历,当访问某个节点时候,将该节点存储的控件释放 public void destroy(TreeNoder treeNoderElement){ if(treeNoderElement != null){ //删除左子树 destroy(treeNoderElement.leftChild); //删除右子树 destroy(treeNoderElement.rightChild); //最后要将这个节点也就是 相对根节点置null 也就是删除 treeNoderElement = null; } } //这个是输出这棵树 public void traverse(TreeNoder treeNoder){ //先带有一个标志 System.out.println("KEY" + treeNoder.key + "--name:" + treeNoder.data); //然后就是老套路递归左子树 traverse(treeNoder.leftChild); //紧接着右子树 traverse(treeNoder.rightChild); } //前序遍历-------- public void preOrder(TreeNoder treeNoder){ //前序遍历第一下肯定是输出根节点的嘛 if(treeNoder != null){ //这个方法就是输出一下根节点,至于为什么要写一个方法 还是为了方便调用呗 //以后左子树也要调用这个方法,右边的也是 visted(treeNoder); //按照前序遍历的规则肯定就是先根再左边再右边 preOrder(treeNoder.leftChild); preOrder(treeNoder.rightChild); } } //接下来中序遍历 就是按照 "左根右"的方式 public void inOrder(TreeNoder treeNoder){ if(treeNoder != null){ inOrder(treeNoder.leftChild); visted(treeNoder); inOrder(treeNoder.rightChild); } } //接下来后序遍历 就是按照 "左右根"的方式 public void postOrder(TreeNoder treeNoder){ if(treeNoder != null){ postOrder(treeNoder.leftChild); postOrder(treeNoder.rightChild); visted(treeNoder); } } public void visted(TreeNoder treeNoder){ treeNoder.isVisted = true; System.out.println("KEY" + treeNoder.key + "--name:" + treeNoder.data); } public static void main(String[] args) { Tree t = new Tree(); t.createTree(t.root); System.out.println("这棵树的size为" + t.size()); System.out.println("这棵树的高为" + t.height()); System.out.println("*******(前序遍历)-LSM-[ABDECF]遍历*****************"); t.preOrder(t.root); System.out.println("*******(中序遍历)-LSM-[DBEACF]遍历*****************"); t.inOrder(t.root); System.out.println("*******(后序遍历)-LSM-[DEBFCA]遍历*****************"); t.postOrder(t.root); } } /* * 二叉树节点的数据结构 * @author LSM */ class TreeNoder{ int key = 0; //这个主要是为了记录他遍历的顺序 String data = null; //这个主要是为了记录他节点的数据 boolean isVisted = false; //先设置为false TreeNoder leftChild = null; TreeNoder rightChild = null; public TreeNoder(int key ,String data){ this.key = key; this.data = data; this.leftChild = null; this.rightChild = null; } }
结果