package com.dy.xidian;public class BiTree { public Node root = null; private int flag = 0; // 将数组转换为完全二叉树 public BiTree(int[] arr) { root = new Node(); root.val = arr[0]; for (int i = 1; i < arr.length; i++) { initBiTree(root, arr[i]); flag = 0; } } public static void main(String[] args) { int[] num = {1, 2, 3, 4, 5, 6, 7, 8}; BiTree biTree = new BiTree(num); biTree.preOrder(biTree.root); System.out.println(""); biTree.inOrder(biTree.root); System.out.println(""); biTree.postOrder(biTree.root); } static class Node { int val; Node LChild; Node RChild; } //在进行数的初始化时对树采用先序遍历的方式来寻找插入节点的位置 private void initBiTree(Node node, int val) { if (node != null && flag == 0) { if(node.LChild == null || node.RChild == null){ if (node.val * 2 == val) { node.LChild = new Node(); node.LChild.val = val; flag = 1; return; } else if (node.val * 2 + 1 == val) { node.RChild = new Node(); node.RChild.val = val; flag = 1; return; } } initBiTree(node.LChild, val); initBiTree(node.RChild, val); } } // 先序遍历,碰到节点就是先访问 public void preOrder(Node _root) { if (_root != null) { System.out.print(_root.val); preOrder(_root.LChild); preOrder(_root.RChild); } } // 中序遍历,碰到节点等一会 public void inOrder(Node _root) { if (_root != null) { inOrder(_root.LChild); System.out.print(_root.val); inOrder(_root.RChild); } } // 后序遍历,碰到节点后访问 public void postOrder(Node _root) { if (_root != null) { postOrder(_root.LChild); postOrder(_root.RChild); System.out.print(_root.val); } }}
上面的程序中先对树进行初始化操作,然后给出了先序、中序和后序遍历的方式。在遍历的时候采用递归算法。
通过在栈的进行遍历操作
//先序遍历 public void preOrder2(Node _root) { Node p = _root; Stackstack = new Stack(); while (p != null || !stack.empty()) { if (p != null) { System.out.print(p.val); stack.push(p); p = p.LChild; } else { p = stack.pop(); p = p.RChild; } } } //中序遍历 public void inOrder2(Node _root){ Node p = _root; Stack stack = new Stack<>(); while(p != null || !stack.empty()){ if(p != null){ stack.push(p); p = p.LChild; } else{ p = stack.pop(); System.out.print(p.val); p = p.RChild; } } }
层次遍历
public void levelOrder(Node _root) { Node p = _root; Queuequeue = new LinkedList<>(); queue.offer(p); //入队操作 while (!queue.isEmpty()) { p = queue.poll(); //出队操作 System.out.println(p.val); if (p.LChild != null) queue.offer(p.LChild); if (p.RChild != null) queue.offer(p.RChild); }}
在进行层次遍历时使用队列进行操作。
总结
二叉树的遍历是重中之重,需要熟练掌握
练习
- 判断给定的二叉树是否是完全二叉树(层次遍历)
- 将一个二叉树上所有节点的左、右子树进行交换
- 打印一个节点的所有祖先节点(非递归后续遍历)
- 求非空二叉树b的宽度(即具有节点数最大的那一层节点的个数)