1、二叉树深度与广度遍历
1.1 二叉树层次遍历
思路:
访问根节点,并将根节点入队。
当队列不空的时候,重复以下操作。
1、弹出一个元素。作为当前的根节点。
2、如果根节点有左孩子,访问左孩子,并将左孩子入队。
3、如果根节点有右孩子,访问右孩子,并将右孩子入队。
public void levelOrder(TreeNode root) {
//使用队列,先进先出
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
TreeNode temp = queue.poll();
System.out.print(temp.val + " ");
if (temp.left != null) {
queue.offer(temp.left);
}
if (temp.right != null) {
queue.offer(temp.right);
}
}
}
/**
* 尾结点标记法
*
* @param root
*/
public static void printTreeByLevel(Node root) {
Queue<Node> queue = new LinkedList<>();
queue.add(root);
Node tail = root;
Node tmp = root;
while (!queue.isEmpty()) {
Node node = queue.poll();
if (node.left != null) {
queue.add(node.left);
tmp = node.left;
}
if (node.right != null) {
queue.add(node.right);
tmp = node.right;
}
System.out.print(node.val + " ");
if (node == tail) {
System.out.println();
tail = tmp;
}
}
}
1.2 深度遍历(先根遍历)
public void deep(TreeNode root){
if(root==null){
return;
}
LinkedList<TreeNode> stack=new LinkedList<TreeNode>();
stack.push(root);
if(!stack.isEmpty()){
TreeNode node=stack.pop();
System.out.println(node.data);
if(node.right!=null){
stack.push(node.right);
}
if(node.left!=null){
stack.push(node.left);
}
}
}
2、二叉树非递归实现
2.1 递归遍历
//前序
public static void preTraversal(Node root){
if(root==null)
return ;
System.out.println(root.value);
preTraversal(root.left);
preTraversal(root.right);
}
//中序
public static void midTraversal(Node root){
if(root==null)
return;
preTraversal(root.left);
System.out.println(root.value);
preTraversal(root.right);
}
//后序
public static void postTraversal(Node root){
if(root==null)
return;
preTraversal(root.left);
preTraversal(root.right);
System.out.println(root.value);
}
2.2 非递归
非递归通过栈来实现
- 非递归先序
public static void preOrder(Node root){
if(root==null)
return;
Stack<Node> stack=new Stack<Node>();
Node node=root;
stack.push(node);
//出栈、输出、入右、入左
while(!stack.isEmpty()){
node=stack.pop();
System.out.println(node.value);
if(node.right!=null){
stack.push(node.right);
}
if(node.left!=null){
stack.push(node.left);
}
}
}
- 中序遍历
/**
* 二叉树的中序遍历:
* 遍历时会重复遍历最左子节点
* 因此不能一直指针指向左遍历
* 当左为空时,调整指针指向右节点
*
* @param root
*/
public void midOrder(Node root){
if(root==null)
return;
Stack<Node> stack=new Stack<Node>();
Node node=root;
//先将left节点全部入栈,再出栈输出,最后node指向rught节点
while(node!=null||!stack.isEmpty()){
if(node!=null){
stack.push(node);
node=node.left;
}else{
node=stack.pop();
System.out.println(node.value);
node=node.right;
}
}
}
- 后序遍历
public void postOrder(Node root){
if(root==null)
return;
Stack<Node> stack1=new Stack<Node>();//子节点
Stack<Node> stack2=new Stack<Node>();//根节点
Node node=root;
stack1.push(node);
//将已stack1出栈从左到右加入到Stack2
while(!stack1.isEmpty()){
node=stack1.pop();
stack2.push(node);
if(node.left!=null){
stack1.push(node.letf);
}
if(node.right!=null){
stack1.push(node.right);
}
}
while(!stack2.isEmpty()){
System.out.println(stack2.pop()+" ");
}
}
3、其他操作
3.1 求二叉树的深度
*递归*
public int treeDepth(TreeNode root){
if(root==null){
return 0;
}
int nleft=treeDepth(root.left);
int nright=treeDepth(root.right);
return nleft>nright?(nleft+1):(nright+1);
}
*非递归*
public int findDepth(TreeNode root){
if(root==null){
return 0;
}
TreeNode current=null;
LinkedList queue=new LinkedList();
queue.offer(root);
int cur,last;//保存层的节点数
int level=0;
while(!queue.isEmpty()){
cur=0;
last=queue.size();
//cur<last控制每次只如一层节点到队列
while(cur<last){
current=queue.poll();
cur++;
if(current.left!=null){
queue.offer(current.left);
}
if(current.right!=null){
queue.offer(current.right);
}
}
level++;
}
return level;
}
3.2 是否为平衡二叉树
从下往上遍历,如果子树是平衡二叉树,则返回子树高度,否则返回-1
public static boolean isBalanceBinary(Node root) {
if (maxDepth(root) == -1) {
return Boolean.FALSE;
}
return Boolean.TRUE;
}
public static int maxDepth(Node node){
if (node == null){
return 0;
}
int left = maxDepth(node.left);
int right = maxDepth(node.right);
if (left == -1 || right == -1 || left-right > 1 || right-left > 1){
return -1;
}
return Math.max(left, right) + 1;
}
3.3 清除某个子树的所有节点
public void clear(BinaryTreeNode node){
if(node!=null){
clear(node.getLeft());
clear(node.getRight());
node=null;
}
}
3.4 节点总个数
public int size(BinaryTreeNode node){
if(node==null){
return 0;
}else{
return 1+size(node.getLeft())+size(node.getRight());
}
}
// 或
public static int numsOfNoChildNode(Node root) {
if (root == null) {
return 0;
}
if (root.left == null && root.right == null) {
return 1;
}
return numsOfNoChildNode(root.left) + numsOfNoChildNode(root.right);
}
3.5 获取最大值
public static int getMax(Node node) {
if (node == null) {
return -1;
}
int left = getMax(node.left);
int right = getMax(node.right);
if (left > right) {
left = right;
}
if (left > node.val) {
left = node.val;
}
return left;
}
3.6 第K层节点数
public static int numsOfkLevelTreeNode(Node root, int k) {
if (root == null || k < 1) {
return 0;
}
if (k == 1) {
return 1;
}
int numsLeft = numsOfkLevelTreeNode(root.left, k - 1);
int numsRight = numsOfkLevelTreeNode(root.right, k - 1);
return numsLeft + numsRight;
}
3.7 二叉树的创建
private static Node create(Integer []array,int index){
Node tn = null;
if (index<array.length) {
Integer value = array[index];
if (value == null) {
return null;
}
tn = new Node();
tn.data=value;
tn.left = create(array, 2*index+1);
tn.right = create(array, 2*index+2);
return tn;
}
return tn;
}
// 或
public static Node createTree(int[] arr, int index) {
if (index >= arr.length) {
return null;
}
Node root = new Node(arr[index]);
root.left = createTree(arr, 2 * index + 1);
root.right = createTree(arr, 2 * index + 2);
return root;
}
4、二叉树比较
4.1 是否相同
boolean isSameTreeNode(Node t1, Node t2) {
if (t1 == null && t2 == null) {
return true;
} else if (t1 == null || t2 == null) {
return false;
}
if (t1.val != t2.val) {
return false;
}
boolean left = isSameTreeNode(t1.left, t2.left);
boolean right = isSameTreeNode(t1.right, t2.right);
return left && right;
}
4.2 镜像转换
Node mirrorTreeNode(Node root) {
if (root == null) {
return null;
}
Node left = mirrorTreeNode(root.left);
Node right = mirrorTreeNode(root.right);
root.left = right;
root.right = left;
return root;
}
4.3 是否为镜像
boolean isMirror(Node t1, Node t2) {
if (t1 == null && t2 == null) {
return true;
}
if (t1 == null || t2 == null) {
return false;
}
if (t1.val != t2.val) {
return false;
}
return isMirror(t1.left, t2.right) && isMirror(t1.right, t2.left);
}