Java-二叉树的底层实现1
在实现二叉树之前,我们要对其有充分了解:
1.什么是二叉树?
·简单来说,二叉树就是带两个分支的链表,每个节点里存着一个数据,而每个节点又有两个用引用串联起来的子节点(左孩子和右孩子),孩子里面也同样存着数据,而孩子又有孩子....
2.二叉树的优点
·顺序表查找快但增删慢
·链表查找慢但增删快
·二叉树是完美融合二者优点的一种数据结构,其既保持了链表灵活的结构,使得自身增删快,又能通过层级分布实现高效查询数据
二叉树概念图:

二叉树的灵魂就是递归,整个二叉树的底层实现大多都离不开递归
1.定义节点
我们需要像链表一样,利用静态内部类描述出一个个节点TreeNode:
public class MyBinarryTree {
public static class TreeNode{
public char val;
public TreeNode left;
public TreeNode right;
public TreeNode(char val){
this.val = val;
}
}
public static int usedSize;
}
2.实现接口
接口里包含了接下来要实现的所有方法,在这篇博客充当目录的存在
public interface IBinarryTree {
1.void preOrder(TreeNode root); 前序遍历 打印
2.void inOrder(TreeNode root);中序遍历 打印
3.void postOrder(TreeNode root); 后序遍历 打印
4.void levelOrder(TreeNode root);层序遍历 自上而下,从左到右 打印
5.int size(TreeNode root);求节点数
6.int getLeafNodeCount(TreeNode root);获得叶子节点的数量
7.int getKLeveNodeCount(TreeNode root, int k);.获得二叉树第K层节点个数
8.int getHeight(TreeNode root);获得二叉树的高度
9.TreeNode find(TreeNode root, char val);查找节点
public static class TreeNode {
public char val;
public TreeNode left;
public TreeNode right;
public TreeNode(char val) {
this.val = val;
}
}
}
一、前序遍历(preOrder)
概念图(画的不是很好):

代码实现:
@Override
public void preOrder(IBinarryTree.TreeNode root) {
if(root==null){
return;
}
System.out.print(root.val+" ");
preOrder(root.left);
preOrder(root.right);
}
思路:先从左边开始,遇到节点则打印其中的值,接下来不断递归,顺序为:
A->B->D->E->C->F->G
二、中序遍历(inOrder)
概念图:

代码实现:
@Override
public void inOrder(IBinarryTree.TreeNode root) {
if(root==null){
return;
}
inOrder(root.left);
System.out.print(root.val+" ");
inOrder(root.right);
}
思路:碰到节点先不打印其中的值,先检查这个节点是否还存在左孩子,如果不存在则打印val
D->B->E->A->F->C->G
三、后序遍历(postOrder)
概念图:

代码实现:
@Override
public void postOrder(IBinarryTree.TreeNode root) {
if(root==null){
return;
}
postOrder(root.left);
postOrder(root.right);
System.out.print(root.val+" ");
}
思路:我们碰到节点先不急着打印val,先检查该节点是否无左右孩子,如果左右孩子都为null,则打印val
D->E->B->F->G->C->A
四、层序遍历(levelOrder)

代码实现:
@Override
public void levelOrder(IBinarryTree.TreeNode root) {
if(root==null){
return;
}
Queue<IBinarryTree.TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
IBinarryTree.TreeNode cur = queue.poll();
System.out.print(cur.val+" ");
if(cur.left!=null){
queue.offer(cur.left);
}
if(cur.right!= null){
queue.offer(cur.right);
}
}
思路:层序遍历是一种自上而下,从左到右的打印,所以我们需要借助队列的先进先出的特性,先offer一个根节点,然后将这个根节点cur,poll吐出来并打印的同时检查其是否有左右孩子,如果有,则queue继续offer,cur的左右孩子进来,不断循环,直到队列为空
五、size(求节点个数)
代码实现:
@Override
public int size(IBinarryTree.TreeNode root) {
if(root==null){
return 0;
}
return size(root.left) + size(root.right) + 1;
}
思路:通过不断递归,直到走到叶子节点的孩子(空气,也就是null),返回0
六、getLeafNodeCount(获得叶子节点个数)
代码实现:
@Override
public int getLeafNodeCount(IBinarryTree.TreeNode root) {
if(root==null){
return 0;
}
if(root.left==null&& root.right==null){
return 1;
}
return getLeafNodeCount(root.left) + getLeafNodeCount(root.right);
}
思路:叶子节点就是左右孩子都为null的节点,所以我们依然利用递归
七、getKlevelNodeCount(获得第K层节点个数)
代码实现:
@Override
public int getKLeveNodeCount(IBinarryTree.TreeNode root, int k) {
if(root==null){
return 0;
}
if(k==1){
return 1;
}
return getKLeveNodeCount(root.left,k-1) +getKLeveNodeCount(root.right,k-1);
}
利用递归,每走一次递归就令K-1
八、getHeight(获得二叉树的高度)
代码实现:
@Override
public int getHeight(IBinarryTree.TreeNode root) {
if(root==null){
return 0;
}
int leftH = getHeight(root.left);
int rightH = getHeight(root.right);
int maxH = leftH>rightH?leftH:rightH;
return maxH+1;
}
九、find(查找节点)
代码实现:
@Override
public IBinarryTree.TreeNode find(IBinarryTree.TreeNode root, char val) {
if(root==null){
return null;
}
if(root.val==val){
return root;
}
IBinarryTree.TreeNode cur1 = find(root.left,val);
if(cur1!=null){
return cur1;
}
IBinarryTree.TreeNode cur2 = find(root.right,val)
if(cur2!=null){
return cur2;
}
return null;
}
更多推荐

所有评论(0)