二叉树的建立和前序、中序、后序的遍历及高度和叶子节点的个数
二叉树
- 建立一棵采用二叉链表结构存储的二叉树。
- 分别采用递归和非递归两种方式对该二叉树进行先序、中序和后序遍历。
- 求二叉树的高度以及二叉树中叶子结点的数目。
1 package BinaryTree; 2 import java.util.*; 3 @SuppressWarnings("all") 4 public class BinaryTree { 5 private TreeNode root=null; 6 public BinaryTree(){ 7 root=new TreeNode(1,"A"); 8 } 9 //创建二叉树 10 public void createBinaryTree(){ 11 TreeNode nodeB=new TreeNode(2,"B"); 12 TreeNode nodeC=new TreeNode(3,"C"); 13 TreeNode nodeD=new TreeNode(4,"D"); 14 TreeNode nodeE=new TreeNode(5,"E"); 15 TreeNode nodeF=new TreeNode(6,"F"); 16 root.leftChild=nodeB; 17 root.rightChild=nodeC; 18 nodeB.leftChild=nodeD; 19 nodeB.rightChild=nodeE; 20 nodeC.rightChild=nodeF; 21 } 22 //二叉树的创建 23 public void createBinaryTreePre (ArrayList<String> data ){ 24 createBinaryTreePre(data.size(),data); 25 } 26 private TreeNode createBinaryTreePre(int size, ArrayList<String> data) { 27 if (data.size()==0){ 28 return null; 29 } 30 Object d=data.get(0); 31 TreeNode node; 32 int index=size-data.size(); 33 if (d.equals("#")){ 34 node=null; 35 data.remove(0); 36 return node; 37 } 38 node=new TreeNode(index,d); 39 if (index==0){ 40 root=node; 41 } 42 data.remove(0); 43 node.leftChild=createBinaryTreePre(size,data); 44 node.rightChild=createBinaryTreePre(size,data); 45 return node; 46 } 47 //二叉树节点类定义 48 public class TreeNode<T>{ 49 private int index; 50 private T data; 51 private TreeNode leftChild; 52 private TreeNode rightChild; 53 public TreeNode(int index,T data){ 54 this.index=index; 55 this.data=data; 56 this.leftChild=null; 57 this.rightChild=null; 58 } 59 60 public int getIndex() { 61 return index; 62 } 63 public void setIndex(int index) { 64 this.index = index; 65 } 66 public T getData() { 67 return data; 68 } 69 public void setData(T data) { 70 this.data = data; 71 } 72 } 73 public void preOrder(TreeNode root){ 74 if (root==null){ 75 return; 76 }else{ 77 System.out.print(root.getData()+" "); 78 preOrder(root.leftChild); 79 preOrder(root.rightChild); 80 } 81 } 82 //前序递归实现遍历二叉树 83 public static void porOrder(TreeNode root) { 84 if(root==null) { 85 return; 86 }else { 87 System.out.print ( root.getData()+" "); 88 //递归:自己调用自己 89 porOrder(root.leftChild); 90 porOrder(root.rightChild); 91 } 92 } 93 //中序递归实现遍历二叉树 94 public static void midOrder(TreeNode root){ 95 if (root==null){ 96 return; 97 }else { 98 midOrder(root.leftChild); 99 System.out.print ( root.getData()+" "); 100 midOrder(root.rightChild); 101 } 102 } 103 //后序递归遍历实现二叉树 104 public static void afterOrder(TreeNode root) { 105 if(root==null) { 106 return; 107 }else { 108 afterOrder(root.leftChild); 109 afterOrder(root.rightChild); 110 System.out.print(root.getData()+" "); 111 } 112 } 113 //前序非递归遍历实现二叉树 114 public static void porOrder1(TreeNode root) { 115 if(root==null) { 116 return ; 117 } 118 Stack<TreeNode> stack=new Stack<TreeNode>(); 119 stack.push(root); 120 while(!stack.isEmpty()) { 121 TreeNode node=stack.pop(); 122 System.out.print(node.getData()+" "); 123 if(node.rightChild!=null) { 124 stack.push(node.rightChild); 125 } 126 if(node.leftChild!=null) { 127 stack.push(node.leftChild); 128 } 129 130 } 131 } 132 //中序非递归实现二叉树 133 public static void midOrder1(TreeNode root) { 134 if(root==null) { 135 return; 136 } 137 Stack<TreeNode> stack=new Stack<>(); 138 TreeNode p=root; 139 while(p!=null||!stack.isEmpty()) { 140 while(p!=null) { 141 stack.push(p); 142 p=p.leftChild; 143 } 144 if(!stack.isEmpty()) { 145 p=stack.pop(); 146 System.out.print(p.getData()+" "); 147 p=p.rightChild; 148 } 149 150 } 151 } 152 //后序非递归实现二叉树 153 public static void afterOrder1(TreeNode root) { 154 if(root==null) { 155 return; 156 } 157 Stack<TreeNode> stack=new Stack<>(); 158 TreeNode p,q; 159 p=root;q=null; 160 while(p!=null||!stack.isEmpty()) { 161 while(p!=null) { 162 stack.push(p); 163 p=p.leftChild; 164 } 165 if(!stack.isEmpty()) { 166 p=stack.peek(); 167 if(p.rightChild==null||p.rightChild==q) { 168 stack.pop(); 169 System.out.print(p.getData()+" "); 170 q=p; 171 p=null; 172 }else { 173 p=p.rightChild; 174 } 175 } 176 }} 177 //求二叉树的高度 178 public int getHeight(){ 179 return getHeight(root); 180 } 181 private int getHeight(TreeNode root){ 182 if (root==null) { 183 return 0; 184 }else{ 185 int i=getHeight(root.leftChild); 186 int j=getHeight(root.rightChild); 187 return (i<j)?j+1:i+1; 188 } 189 } 190 //获得叶子节点的数目 191 public int getLeaf() { 192 return getLeaf(root); 193 } 194 private int getLeaf(TreeNode root) { 195 if(root!=null) { 196 if(root.leftChild==null&&root.rightChild==null) { 197 return 1; 198 } 199 return getLeaf(root.leftChild)+getLeaf(root.rightChild); 200 } 201 202 return 0; 203 } 204 public static void main(String[]args) { 205 BinaryTree tree=new BinaryTree(); 206 ArrayList<String> lists=new ArrayList(); 207 String[] s=new String[]{"A","B","D","#","#","E","#","#","C","#","F","#","#"}; 208 for (String str:s){ 209 lists.add(str); 210 } 211 tree.createBinaryTreePre(lists); 212 System.out.println("前序递归遍历:"); 213 porOrder(tree.root); 214 System.out.println(); 215 System.out.println("中序递归遍历:"); 216 midOrder(tree.root); 217 System.out.println(); 218 System.out.println("后序递归遍历:"); 219 afterOrder(tree.root); 220 System.out.println(); 221 System.out.println("前序非递归遍历:"); 222 porOrder1(tree.root); 223 System.out.println(); 224 System.out.println("中序非递归遍历:"); 225 midOrder1(tree.root); 226 System.out.println(); 227 System.out.println("后序非递归遍历:"); 228 afterOrder1(tree.root); 229 System.out.println(); 230 System.out.println("二叉树数的高度为: "+tree.getHeight()); 231 System.out.println("二叉树的叶子节点的个数为: "+tree.getLeaf()); 232 } 233 }
最后在编写程序 时遇到的问题
- Stack.pop与Stack.peek的区别
相同点:都是取出栈顶的元素的值
不同点:.pop会改变栈顶元素的值,.peek不会改变栈顶元素的值