Java二叉树遍历不完_java-二叉树遍历

1 //先简单建树-按完全二叉树节点插入顺序建树,即层序遍历。

2

3 /**二叉树:每个节点最多两个孩子节点(计划生育-最多生二胎);4 * 完全二叉树(遏制人口老龄化:必须生两胎,否则不准后代传宗接代):5 * 根节点(爷爷)先生,生不满两胎接着生,爷爷生完,老大(左爸爸)生,6 * 生不满二胎,爷爷的小儿子不准生,。。。依次类推。7 **/

8

9 /**按层间遍历顺序加入节点10 层序遍历用队列,根节点入队,11 执行循环,当队列不为空{对首X出队,若X左孩子非空,入队,右孩子非空入队}12 */

13

14 /**层序遍历(用队列先进先出性能实①现先访问根节点(第一层)15 ②再依次访问根节点的左右孩子节点(第二层)16 ③再依次访问根节点左右孩子节点的左右孙子节点(第三层),17 ④.....18 */

19

20 /**?21 * 功能22 * ①,建树--体会完全二叉树,添加节点过程(先建简单的,主要还是体会各种遍历)23 * ②,4种遍历,7种方法,前、中、后序递归遍历,前、中、后非递归遍历,层序遍历。24 * ③,删树,25 * ④,求树高26 * ⑤,树状打印27 * ⑥,28 */

29

30 importjava.util.Arrays;31 importjava.util.LinkedList;32 importjava.util.Queue;33 importjava.util.Stack;34

35 public classEasy_BiTree {36 //内部Node类

37 public classNode {38 private int data=Integer.MAX_VALUE;39 private Node lchild=null;40 private Node rchild=null;41

42 publicNode(){}43 public Node(intdata){44 this.data=data;45 }46 }47

48 private Node root=null;49 private int size=0;50 publicEasy_BiTree(){}51

52 //添加节点

53 public void addNode(Node root,intdata){54 //根节点

55 if(size==0){56 this.root=newNode(data);57 size++;58 }else{59 Node newNode=newNode(data);60

61 //添加节点用层序遍历方法目的不是为了遍历每一个节点,而是按层次顺序找到第一个孩子不满(没生二胎)的节点62 //当遇到孩子节点没满的Node,添加节点-退出;

63 Queue queue=new LinkedList<>();64 queue.add(root);65 while(!queue.isEmpty()){66 Node curroot=queue.poll();67 if(curroot.lchild!=null)68 queue.add(curroot.lchild);69 else{70 curroot.lchild=newNode;71 size++;72 return;73 }74 if(curroot.rchild!=null)75 queue.add(curroot.rchild);76 else{77 curroot.rchild=newNode;78 size++;79 return;80 }81 }82 }83 }84

85 //遍历-前序非递归,

86

87 /**

88 * ①顺着根节点的左孩子一路到底,一边输出一边入栈,89 * ②到底后,判断栈顶有没有右子树,有以右子节点为根节点重复①,没有则出栈,90 */

91 public voidpreOrder(Node root){92 if(size==0)93 System.out.println("树空无遍历");94 else{95 System.out.print("树前序非递归: ");96 Stack stack=new Stack<>();97 while(root!=null||!stack.isEmpty()){98 while(root!=null){99 System.out.print(root.data+" ");100 stack.add(root);101 root=root.lchild;102 }103 if(!stack.isEmpty()){104 root=stack.pop();105 root=root.rchild;106 }107 }108 System.out.println();109 }110 }111 //遍历-中序非递归,

112 public voidinOrder(Node root){113 if(size==0)114 System.out.println("树空,无遍历");115 else{116 System.out.print("树中序非递归: ");117 Stack stack=new Stack<>();118 while(root!=null||!stack.isEmpty()){119 while(root!=null){120 stack.add(root);121 root=root.lchild;122 }123 if(!stack.isEmpty()){124 root=stack.pop();125 System.out.print(root.data+" ");126 root=root.rchild;127 }128 }129 System.out.println();130 }131 }132 //遍历-后序非递归,

133 /**

134 *①顺着根节点的左孩子一路到底,入栈,135 * ②到底后,判断栈顶有没有右子树,没有出栈,输出136 * ③有右子节点,右子节点遍历之前不能出栈,preNode,即标识右子节点有没有遍历,137 * 以右子节点为根节点重复①,②③138 */

139 public voidpostOrder(Node root){140 if(size==0)141 System.out.println("树空,无遍历");142 else{143 System.out.print("树后序非递归: ");144 Stack stack=new Stack<>();145 while(root!=null||!stack.isEmpty()){146 while(root!=null){147 stack.push(root);148 root=root.lchild;149 }150 boolean tag=true;151 Node preNode=null;152 while(!stack.isEmpty()&&tag==true){153 root=stack.peek();154 if(root.rchild==preNode){155 root=stack.pop();156 System.out.print(root.data+" ");157 if(stack.isEmpty()){158 System.out.println();159 return;160 }161 else

162 preNode=root;163 }else{164 root=root.rchild;165 tag=false;166 }167 }168 }169 System.out.println();170 }171 }172

173 /**

174 * 额。。递归写起来是很简单,我也说不好原理,233175 */

176 //遍历-前序递归,

177 public voidpreOrderRec(Node root){178 if(root==null)179 return;180 else{181 System.out.print(root.data+" ");182 preOrderRec(root.lchild);183 preOrderRec(root.rchild);184 }185 }186 //遍历-中序递归,

187 public voidinOrderRec(Node root){188 if(root==null)189 return;190 else{191 inOrderRec(root.lchild);192 System.out.print(root.data+" ");193 inOrderRec(root.rchild);194 }195 }196 //遍历-后序递归,

197 public voidpostOrderRec(Node root){198 if(root==null)199 return;200 else{201 postOrderRec(root.lchild);202 postOrderRec(root.rchild);203 System.out.print(root.data+" ");204 }205 }206

207

208

209 //遍历,-层间遍历

210 public voidlevelOrder(Node root){211 if(this.size==0)212 System.out.println("空树,无法遍历");213 else{214 System.out.println("树层间遍历:");215 Queue queue=new LinkedList<>();216 queue.add(root);217 while(!queue.isEmpty()){218 Node curroot=queue.poll();219 System.out.print(curroot.data+" ");220 if(curroot.lchild!=null)221 queue.add(curroot.lchild);222 if(curroot.rchild!=null)223 queue.add(curroot.rchild);224 }225 System.out.println();226 }227 }228

229 //删树230 //java有内存回收机制,只要把根节点状态,换成空树根节点状态即可;231 //C++也是类似遍历一遍,把遍历到的每一个节点free;232

233 //呃。。。。我猜的,哈哈哈哈哈哈哈哈

234 public voiddeleteTree(){235 this.root=null;236 size=0;237 }238

239 /**

240 * 树高-递归和非递归方法241 * 完全二叉树,节点和高有方程,log(size)向下取整+1242 * 这里用非特殊二叉树求树高,243 */

244

245 //转载:https://blog.csdn.net/shijie97/article/details/79775399

246 /**非递归-队列,247 * 根节点入队,出队,添加第二层,添加完后记录队size(0/1/2),然后将(0/1/2)个出队,将他们的孩子入队,记录每一层248 * 孩子数,遍历完,即可知道层数249 */

250 public inttreeHeight(Node root){251 if(root==null)252 return 0;253 else if(size==1)254 return 1;255 else{256 Queue queue=new LinkedList<>();257 queue.add(root);258 int height=0;259 //记录每层孩子个数,root入队长为1

260 int len=1;261 while(!queue.isEmpty()){262 int length=0;263 for(int i=0;i

281 public inttreeHeightRec(Node root){282 if(root==null)283 return 0;284 else{285 int a =treeHeightRec(root.lchild);286 int b =treeHeightRec(root.rchild);287 return (a>b)?(a+1):(b+1);288 }289 }290

291 //树状打印

292 /**

293 * 思路:先确定树高h-最后一层2^(h-1)个数,好知道根节点放在哪里(预留空间保证根再中间)294 * 设每个data三位数=space,元素之间空三位数,每行 (2^H+1)*3 个“ ”295 * _数_数_数_数_数_ 每层2^(h-1)个数,2^(h-1)+1个space,最后一行长2^h+1个space296 *297 * 当层数多的时候稍乱,2333不想弄了,298 */

299 public voidprintTree(Node root){300 int H=treeHeight(root);301 int h=H;302 //System.out.println("树高:"+H);

303 if(H==0)304 System.out.println("树空,无打印");305 else{306 System.out.println("打印树:");307 Queue queue=new LinkedList<>();308 queue.add(root);309 int height=1;310 //记录每层孩子个数

311 int len=1;312 while(h>0){313 int length=0;314 String space="";315 for(int i=0;i

322 System.out.print(space+curroot.data);323

324 if(curroot.lchild!=null){325 queue.add(curroot.lchild);326 }327 else

328 queue.add(newNode());329 length++;330 if(curroot.rchild!=null){331 queue.add(curroot.rchild);332 }333 else

334 queue.add(newNode());335 length++;336 }337 System.out.println();338 System.out.println();339 len=length;340 height++;341 h--;342 }343 System.out.println();344 }345 }346

347

348 /**

349 *350 * 根据先序和中序创建二叉树351 * 转载:https://www.cnblogs.com/tuyang1129/p/11647443.html

352 * ①先序的第一个元素为根节点,②找出这个根节点在中序中的位置x,xx左边是根节点的左子树,右边是右子树353 * ③递归建树354 *355 */

356

357 public int getIndex(int data,int[] array){358 int num =Integer.MAX_VALUE;359 for(int i=0;i

366 public Node preIn_BiTree(int[] pre,int[] in){367 if(pre.length==0){368 return null;369 }else if(pre.length==1){370 return new Node(pre[0]);371 }372 Node root=new Node(pre[0]);373

374 int index=getIndex(pre[0],in);375

376 //左子树

377 int[] preleft= Arrays.copyOfRange(pre,1,index+1);378 int[] inleft=Arrays.copyOfRange(in,0,index);379 root.lchild=preIn_BiTree(preleft,inleft);380

381 //右子树

382 int[] preright=Arrays.copyOfRange(pre,index+1,pre.length);383 int[] inright=Arrays.copyOfRange(in,index+1,in.length);384 root.rchild=preIn_BiTree(preright,inright);385

386 returnroot;387

388 }389

390 /**

391 * 根据中序-后续392 * ①后序的第一个元素为根节点,②找出这个根节点在中序中的位置x,x左边是根节点的左子树,右边是右子树393 * ③递归建树394 */

395 public Node inPost_BiTree(int[] in,int[] post){396 if(in.length==0){397 return null;398 }else if(in.length==1){399 return new Node(in[0]);400 }401 Node root=new Node(post[post.length-1]);402 int index=getIndex(post[post.length-1],in);403

404 //左子树

405 int[] postleft= Arrays.copyOfRange(post,0,index);406 int[] inleft=Arrays.copyOfRange(in,0,index);407 root.lchild=inPost_BiTree(inleft,postleft);408

409 //右子树

410 int[] postright=Arrays.copyOfRange(post,index,post.length-1);411 int[] inright=Arrays.copyOfRange(in,index+1,in.length);412 root.rchild=inPost_BiTree(inright,postright);413

414 returnroot;415

416 }417

418

419

420

421 public static voidmain(String args[]) {422 /**

423 * 完全二叉树的建立,与二叉树的遍历424 */

425 Easy_BiTree t=newEasy_BiTree();426 t.addNode(t.root,1);427 t.addNode(t.root,2);428 t.addNode(t.root,3);429 t.addNode(t.root,4);430 t.addNode(t.root,5);431 t.addNode(t.root,6);432 t.addNode(t.root,7);433 t.addNode(t.root,8);434 t.addNode(t.root,9);435 t.addNode(t.root,10);436 t.addNode(t.root,11);437 t.addNode(t.root,12);438 t.addNode(t.root,13);439 t.addNode(t.root,14);440 t.addNode(t.root,15);441 t.addNode(t.root,16);442 t.addNode(t.root,17);443 t.addNode(t.root,18);444 t.addNode(t.root,19);445 t.addNode(t.root,20);446 t.addNode(t.root,21);447

448 t.levelOrder(t.root);449 System.out.println("非递归求树高: "+t.treeHeight(t.root));450 System.out.println("递归求树高: "+t.treeHeightRec(t.root));451

452 t.printTree(t.root);453

454 t.preOrder(t.root);455 t.inOrder(t.root);456 t.postOrder(t.root);457

458 System.out.print("树前序递归遍历: ");459 t.preOrderRec(t.root);460 System.out.println();461 System.out.print("树中序递归遍历: ");462 t.inOrderRec(t.root);463 System.out.println();464 System.out.print("树后序递归遍历: ");465 t.postOrderRec(t.root);466 System.out.println();467

468 t.deleteTree();469 System.out.println("非递归求树高: "+t.treeHeight(t.root));470

471

472 /**

473 * 其他建树方法474 */

475 int[] pre={1,2,4,7,3,5,6};476 int[] in={2,7,4,1,5,3,6};477 int[] post={7,4,2,5,6,3,1};478

479 int[] pre1={1,2,3,4,5,6,7};480 int[] in1={2,4,6,7,5,3,1};481 int[] post1={7,6,5,4,3,2,1};482

483

484 System.out.println("pre={1,2,4,7,3,5,6}");485 System.out.println("in={2,7,4,1,5,3,6}");486 Easy_BiTree t2=newEasy_BiTree();487 t2.root=t2.preIn_BiTree(pre,in);488 t2.printTree(t2.root);489

490 System.out.println("pre1={1,2,3,4,5,6,7}");491 System.out.println("in1={2,4,6,7,5,3,1}");492 Easy_BiTree t3=newEasy_BiTree();493 t3.root=t3.preIn_BiTree(pre1,in1);494 t3.printTree(t3.root);495

496 System.out.println("in={2,7,4,1,5,3,6}");497 System.out.println("post={7,4,2,5,6,3,1}");498 Easy_BiTree t4=newEasy_BiTree();499 t4.root=t4.inPost_BiTree(in,post);500 t4.printTree(t4.root);501

502 System.out.println("in1={2,7,4,1,5,3,6}");503 System.out.println("post1={7,4,2,5,6,3,1}");504 Easy_BiTree t5=newEasy_BiTree();505 t5.root=t5.inPost_BiTree(in1,post1);506 t5.printTree(t5.root);507

508 }509 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值