Java二叉树基础

在前篇文章Java集合框架中我们介绍了排序二叉树、平衡二叉树以及红黑树的概念以及常见的增删操作步骤,这次就学习一下二叉树中常见的一些遍历、翻转等算法,之后刷题时如果遇见相关的题型再做补充。

创建

这里以排序二叉树为例:

public class test {
	
	public static void main(String[] args) {
	      int[] arr = {5,3,2,0,4,7,1,9,8};
	      BinarySortTree  binarySortTree = new BinarySortTree();
	      for(int i=0;i<arr.length;i++) {
	    	  binarySortTree.add(new Node(arr[i]));
	      }
	}
}

class BinarySortTree{
	 private Node root;
	 public void add(Node node) {
		 if(root == null) {
			 root =node;
		 }else {
			 root.add(node);
		 }
	 }
}

class Node{
	int value;
	Node leftNode;
	Node rightNode;
	
	public Node(int value) {
		this.value = value;
	}
	
	public void add(Node node) {
		if(node == null) {
			return;
		}
		
		if(node.value < this.value) {
			if(this.leftNode == null) {
				this.leftNode = node;
			}else {
				this.leftNode.add(node);
			}
		}else {
			if(this.rightNode == null) {
				this.rightNode = node;
			}else {
				this.rightNode.add(node);
			}
		}
	}
}

核心思想就是判断当前插入节点的值,与根节点比较,如果小于根节点,就递归插入左子树,如果大于根节点,就递归插入右子树。

遍历

首先看深度优先遍历的前/中/后序遍历(递归和非递归)以及层序遍历方法:

先序遍历:->->右
中序遍历:->->右
后序遍历:->->
public class test {
	public static void main(String[] args) {
	      int[] arr = {5,3,2,0,4,7,1,9,8};
	      BinarySortTree  binarySortTree = new BinarySortTree();
	      for(int i=0;i<arr.length;i++) {
	    	  binarySortTree.add(new Node(arr[i]));
	      }
	      binarySortTree.preTraverse();
	}

}

class BinarySortTree{
	 private Node root;
	 public void add(Node node) {
		 if(root == null) {
			 root =node;
		 }else {
			 root.add(node);
		 }
	 }
	 
	 public void preTraverse() {
		 if(root !=null) {
			 root.preTraverse();
		 }
	 }
}
class Node{
	int value;
	Node leftNode;
	Node rightNode;
	
	public Node(int value) {
		this.value = value;
	}
	
	public void add(Node node) {
		if(node == null) {
			return;
		}
		
		if(node.value < this.value) {
			if(this.leftNode == null) {
				this.leftNode = node;
			}else {
				this.leftNode.add(node);
			}
		}else {
			if(this.rightNode == null) {
				this.rightNode = node;
			}else {
				this.rightNode.add(node);
			}
		}
	}
	
	 public void preTraverse() {
		  //System.out.print(this.value+" ");//前序
		  if(this.leftNode!=null) {
			  this.leftNode.preTraverse();
		  }
		  System.out.print(this.value+" ");//中序
		  if(this.rightNode!=null) {
			  this.rightNode.preTraverse();
		  }
		  //System.out.print(this.value+" ");//后序
	 }
}

这里以中序为例,先访问左子树,再根,再右子树,那么输出的序列应为有序序列,运行结果如下:
在这里插入图片描述
非递归方法:

//先序遍历
public static void preOrder2() {
     if(root == null) return;
     Stack<Node> q = new Stack<Node>();
     q.add(root);
     while(!q.isEmpty()){
          Node temp = q.pop();
          System.out.print(temp.value +" ");
          if(temp.rightNode!=null) q.add(temp.rightNode);
          if(temp.leftNode!=null) q.add(temp.leftNode);
     }
}
//中序遍历
 public void midTraverse() {
		if(root == null) return;
		Stack<Node> stack = new Stack<>();
		while(root!=null || !stack.isEmpty()) {
			while (root!=null) {
			    stack.push(root);
			    root = root.leftNode;
			}
			if(!stack.isEmpty()) {
				root = stack.pop();
				System.out.print(root.value+" ");
				root = root.rightNode;
			}
		}
}
//后序遍历
 public void posTraverse() {
		 List<Integer> list = new ArrayList<>();
		 if(root == null) return;
	     Stack<Node> q = new Stack<Node>();
	     q.add(root);
	     while(!q.isEmpty()){
	          Node temp = q.pop();
	          list.add(temp.value);
	          if(temp.leftNode!=null) q.add(temp.leftNode);
	          if(temp.rightNode!=null) q.add(temp.rightNode);
	     }
	     for(int i=list.size()-1;i>=0;i--) {
	    	 System.out.print(list.get(i)+" ");
	     }
}

接着看层序遍历(BFS广度优先):

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class test {
	
	public static void main(String[] args) {
	      int[] arr = {5,3,2,0,4,7,1,9,8};
	      BinarySortTree  binarySortTree = new BinarySortTree();
	      for(int i=0;i<arr.length;i++) {
	    	  binarySortTree.add(new Node(arr[i]));
	      }
	      binarySortTree.traver_bfs();
	}

}

class BinarySortTree{
	 private Node root;
	 public void add(Node node) {
		 if(root == null) {
			 root = node;
		 }else {
			 root.add(node);
		 }
	 }
	 
	 public void traver_bfs() {
		 if(root!=null) {
			 bfs(root);
		 }	
	 }
	 
	 public void bfs(Node root) {
		 if (root == null) 
			 return;
		 LinkedList<Node> list = new LinkedList<Node>(); 
		 list.add(root);
		 Node currentNode;
		 while(!list.isEmpty()) {
			 currentNode = list.poll();
			 System.out.print(currentNode.value+" ");
			 if(currentNode.leftNode!=null){
				 list.add(currentNode.leftNode);
			 }
			 if(currentNode.rightNode!=null) {
				 list.add(currentNode.rightNode);
			 }
		 }
		
	} 
}
class Node{
	int value;
	Node leftNode;
	Node rightNode;
	
	public Node(int value) {
		this.value = value;
	}
	
	public void add(Node node) {
		if(node == null) {
			return;
		}
		
		if(node.value < this.value) {
			if(this.leftNode == null) {
				this.leftNode = node;
			}else {
				this.leftNode.add(node);
			}
		}else {
			if(this.rightNode == null) {
				this.rightNode = node;
			}else {
				this.rightNode.add(node);
			}
		}
	}
	
}

运行结果如下:
在这里插入图片描述

左右翻转

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class test {
	
	public static void main(String[] args) {
	      int[] arr = {5,3,2,0,4,7,1,9,8};
	      BinarySortTree  binarySortTree = new BinarySortTree();
	      for(int i=0;i<arr.length;i++) {
	    	  binarySortTree.add(new Node(arr[i]));
	      }
	      binarySortTree.invert_tree();
	      binarySortTree.traver_bfs();
	}

}

class BinarySortTree{
	 private Node root;
	 public void add(Node node) {
		 if(root == null) {
			 root = node;
		 }else {
			 root.add(node);
		 }
	 }
	 
	 public void invert_tree() {
		 invert(root);
	 }
	 
	 public void invert(Node root) {
		 if(root == null) return;
		 Node temp = root.leftNode;
		 root.leftNode = root.rightNode;
		 root.rightNode = temp;
		 invert(root.leftNode);
		 invert(root.rightNode);
	} 
	public void traver_bfs() {
		 if(root!=null) {
			 bfs(root);
		 }	
	}
	 
	public void bfs(Node root) {
		 if (root == null) 
			 return;
		 LinkedList<Node> list = new LinkedList<Node>(); 
		 list.add(root);
		 Node currentNode;
		 while(!list.isEmpty()) {
			 currentNode = list.poll();
			 System.out.print(currentNode.value+" ");
			 if(currentNode.leftNode!=null){
				 list.add(currentNode.leftNode);
			 }
			 if(currentNode.rightNode!=null) {
				 list.add(currentNode.rightNode);
			 }
		}
		
	} 
}
class Node{
	int value;
	Node leftNode;
	Node rightNode;
	
	public Node(int value) {
		this.value = value;
	}
	
	public void add(Node node) {
		if(node == null) {
			return;
		}
		
		if(node.value < this.value) {
			if(this.leftNode == null) {
				this.leftNode = node;
			}else {
				this.leftNode.add(node);
			}
		}else {
			if(this.rightNode == null) {
				this.rightNode = node;
			}else {
				this.rightNode.add(node);
			}
		}
	}
	
}

运行结果如下:
在这里插入图片描述

查找最大值

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class test {
	
	public static void main(String[] args) {
	      int[] arr = {7,3,10,12,5,1,9,8,7};
	      BinarySortTree  binarySortTree = new BinarySortTree();
	      for(int i=0;i<arr.length;i++) {
	    	  binarySortTree.add(new Node(arr[i]));
	      }
	      binarySortTree.q_maxValue1();
	      binarySortTree.q_maxValue2();
	}
}

class BinarySortTree{
	 private Node root;
	 public void add(Node node) {
		 if(root == null) {
			 root = node;
		 }else {
			 root.add(node);
		 }
	 }
	 public void q_maxValue1() {
		 int maxValue = maxValue1(root);
		 //System.out.println(maxValue);
	 }
	 public int maxValue1(Node root) {
		 if (root == null) return 0;
		 int right = maxValue1(root.rightNode);
		 return Math.max(root.value, right);
	 }
	 
	 public void q_maxValue2() {
		 int maxValue = maxValue2(root);
		 System.out.println(maxValue);
	 }
	 
	 public int maxValue2(Node root) {
		 if (root == null) {
			 return Integer.MIN_VALUE;
		 }else {
			 int left = maxValue2(root.leftNode);
		     int right = maxValue2(root.rightNode);
		     return Math.max(Math.max(left, right), root.value);
		}
	 }
}
class Node{
	int value;
	Node leftNode;
	Node rightNode;
	
	public Node(int value) {
		this.value = value;
	}
	
	public void add(Node node) {
		if(node == null) {
			return;
		}
		
		if(node.value < this.value) {
			if(this.leftNode == null) {
				this.leftNode = node;
			}else {
				this.leftNode.add(node);
			}
		}else {
			if(this.rightNode == null) {
				this.rightNode = node;
			}else {
				this.rightNode.add(node);
			}
		}
	}	
}

运行结果如下:
在这里插入图片描述

最大深度

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class test {
	
	public static void main(String[] args) {
	      int[] arr = {7,3,10,12,5,1,9,8,7};
	      BinarySortTree  binarySortTree = new BinarySortTree();
	      for(int i=0;i<arr.length;i++) {
	    	  binarySortTree.add(new Node(arr[i]));
	      }
	      binarySortTree.q_maxDepth();
	}

}

class BinarySortTree{
	 private Node root;
	 public void add(Node node) {
		 if(root == null) {
			 root = node;
		 }else {
			 root.add(node);
		 }
	 }
	 public void q_maxDepth() {
		 int maxdepth = maxDepth(root);
		 System.out.println(maxdepth);
	 }
	 public int maxDepth(Node root) {
		    if (root == null) return 0;
		    int left = maxDepth(root.leftNode);
		    int right = maxDepth(root.rightNode);
		    return Math.max(left, right) + 1;
	 }
	 
	
}
class Node{
	int value;
	Node leftNode;
	Node rightNode;
	
	public Node(int value) {
		this.value = value;
	}
	
	public void add(Node node) {
		if(node == null) {
			return;
		}
		
		if(node.value < this.value) {
			if(this.leftNode == null) {
				this.leftNode = node;
			}else {
				this.leftNode.add(node);
			}
		}else {
			if(this.rightNode == null) {
				this.rightNode = node;
			}else {
				this.rightNode.add(node);
			}
		}
	}
	
}

运行结果:
在这里插入图片描述

最小深度

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class test {
	
	public static void main(String[] args) {
	      int[] arr = {7,3,10,12,5,1,9,8,7};
	      BinarySortTree  binarySortTree = new BinarySortTree();
	      for(int i=0;i<arr.length;i++) {
	    	  binarySortTree.add(new Node(arr[i]));
	      }
	      binarySortTree.q_minDepth();
	}

}

class BinarySortTree{
	 private Node root;
	 public void add(Node node) {
		 if(root == null) {
			 root = node;
		 }else {
			 root.add(node);
		 }
	 }
	 public void q_minDepth() {
		 int mindepth = minDepth(root);
		 System.out.println(mindepth);
	 }
	 public int minDepth(Node root) {
		    if (root == null) return 0;
		    int left = minDepth(root.leftNode);
		    int right = minDepth(root.rightNode);
		    if (left == 0) {
		        return right + 1;
		    } else if (right == 0) {
		        return left + 1;
		    } else {
		        return Math.min(left, right) + 1;
		    }
	 }
	 
	
}
class Node{
	int value;
	Node leftNode;
	Node rightNode;
	
	public Node(int value) {
		this.value = value;
	}
	
	public void add(Node node) {
		if(node == null) {
			return;
		}
		
		if(node.value < this.value) {
			if(this.leftNode == null) {
				this.leftNode = node;
			}else {
				this.leftNode.add(node);
			}
		}else {
			if(this.rightNode == null) {
				this.rightNode = node;
			}else {
				this.rightNode.add(node);
			}
		}
	}
	
}

运行结果:
在这里插入图片描述

平衡二叉树判断

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class test {	
	public static void main(String[] args) {
	      int[] arr = {50,25,75,37};
	      BinarySortTree  binarySortTree = new BinarySortTree();
	      for(int i=0;i<arr.length;i++) {
	    	  binarySortTree.add(new Node(arr[i]));
	      }
	      binarySortTree.judgeBalance();
	}
}

class BinarySortTree{
	 private Node root;
	 Boolean isBalance = true; 
	 public void add(Node node) {
		 if(root == null) {
			 root = node;
		 }else {
			 root.add(node);
		 }
	 }
	public void judgeBalance() {
		judgeTree(root);
		System.out.print(isBalance);
	}
	public int judgeTree(Node node) {
		if(node == null || isBalance == false) {
			return 0;
		}
		int judgeLeft = judgeTree(node.leftNode);
		int judgeRight = judgeTree(node.rightNode);
		if(Math.abs(judgeLeft - judgeRight) > 1) {
			isBalance = false;
		}
		return Math.max(judgeLeft, judgeRight)+1;
	}	
}
class Node{
	int value;
	Node leftNode;
	Node rightNode;
	
	public Node(int value) {
		this.value = value;
	}
	
	public void add(Node node) {
		if(node == null) {
			return;
		}
		
		if(node.value < this.value) {
			if(this.leftNode == null) {
				this.leftNode = node;
			}else {
				this.leftNode.add(node);
			}
		}else {
			if(this.rightNode == null) {
				this.rightNode = node;
			}else {
				this.rightNode.add(node);
			}
		}
	}
	
}

排序二叉树判断

这里采用中序遍历,如果前节点不小于当前节点的值,则不符合排序二叉树的条件:

public class test {
	public static void main(String[] args) {
	      int[] arr = {5,3,2,0,4,7,1,9,8};
	      BinarySortTree  binarySortTree = new BinarySortTree();
	      for(int i=0;i<arr.length;i++) {
	    	  binarySortTree.add(new Node(arr[i]));
	      }
	      binarySortTree.midTraverse();
	}

}

class BinarySortTree{
	 private Node root;
	 Boolean isBinarySortTree = true;
	 Node preNode = null;
	 public void add(Node node) {
		 if(root == null) {
			 root =node;
		 }else {
			 root.add(node);
		 }
	 }
	 
	 public void midTraverse() {
		 midTraverse(root);
		 System.out.print(isBinarySortTree);
	 }
	 
	 public void midTraverse(Node root) {
		 if (root != null) {
			 midTraverse(root.leftNode);
		     if(preNode != null && preNode.value>=root.value) isBinarySortTree = false;
		     preNode = root;
		     midTraverse(root.rightNode);
		 }
	 }
}
class Node{
	int value;
	Node leftNode;
	Node rightNode;
	
	public Node(int value) {
		this.value = value;
	}
	
	public void add(Node node) {
		if(node == null) {
			return;
		}
		
		if(node.value < this.value) {
			if(this.leftNode == null) {
				this.leftNode = node;
			}else {
				this.leftNode.add(node);
			}
		}else {
			if(this.rightNode == null) {
				this.rightNode = node;
			}else {
				this.rightNode.add(node);
			}
		}
	}
}

这里由于建树的时候就是建立的排序二叉树,因此输出为true:
在这里插入图片描述

排序二叉树中第K小的元素

在这里插入图片描述
这里其实也可以用中序遍历的方法,为什么中序遍历最后事有序的呢?可以参考上图,如果将每个节点的值投影到坐标轴上,最终得到的就是一个有序序列,而中序遍历的遍历顺序和这种投影所形成的顺序是相通的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值