java实现简单的二叉树ADT

简介: java实现简单的二叉树ADT

边分析边走


首先节点类:


/*
 * 节点
 * value 储存的值
 * left 左节点 right 右节点
 */
public class node {//结点
  public int value;
  public node left;
  public node right;
  public node()
  {
  }
  public node(int value)
  {
    this.value=value;
    this.left=null;
    this.right=null;
  }
  public node(int value,node l,node r)
  {
    this.value=value;
    this.left=l;
    this.right=r;
  }     
}



树类:在这个问题中查找较好理解,最左侧的最小,最右侧的最大


插入:要注意t虽然是root的引用,但是t无法直接改变root的value值,只能改变root的左右节点,(root的左右结构指针)这个可能和C 有点像,我也差异很久为啥root自己不能该然而root.left能改,原来root.left相当于指针,只不过被封装起来。这样理解之和二叉树的插入就很好理解了;


删除节点:删除的规则就是先找到这个点。这个点用这个点的子树可以补上的点填充该点,然后在以这个点为头删除替代的子节点(调用递归)然后在添加到最后情况(只有一个分支,等等)。首先要找到移除的位置,然后移除的那个点分类讨论,如果有两个儿子,就选右边儿子的最左侧那个点替代,然后再子树删除替代的那个点。如果是一个节点,判断是左空还是右空,将这个点指向不空的那个。不空的那个就替代了这个节点。入股左右都是空,那么他自己变空null就删除了。


遍历:前序中序,后序都是递归实现,用队列实现遍历的那种方法就是bfs的雏形。(个人认为)非递归便利要稍微麻烦一点。


import java.util.ArrayDeque;
import java.util.Queue;
/*
 * ADT查找二叉树
 * 规则:
 * 父节点的值要比左侧大,要比右侧小
 */
public class tree {
  public node root;//根
  public tree()
  {root=null;}
  public void makeempty()//变空
  {root=null;;}
  public boolean isempty()//查看是否为空
  {return root==null;}
  public node findmin(node t)//查找最小返回值是node,调用查看结果时需要.value
  {
    if(t==null) {return null;}
    else if(t.left==null) {return t;}
    else return(findmin(t.left)); 
  }
  public node findmax(node t)//查找最大
  {
    if(t==null) {return null;}
    else if(t.right==null) {return t;}
    else return(findmax(t.right));  
  }
  public boolean iscontains(int x)//是否存在
  {
    node current=root;
    if(root==null) {return false;}
    while(current.value!=x&&current!=null) 
    {
      if(xcurrent.value) {current=current.right;}
      if(current==null) {return false;}//在里面判断如果超直接返回
    }
    //如果在这个位置判断是否为空会导致current.value不存在报错
     if(current.value==x) {return true;}    
    return false;   
  }
  public node insert(int x,node t)//插入 t是root的引用
  {     
    node a1=new node(x);
    if(root==null) {root=a1;return root;} //判断 函数其实无法改变参数的值,但是可以调用其指针,改变。所以要直接用root(个人理解) 
    if(t==null) {t=a1;return t;}
     else if(t!=null)
     {      
      if(x=t.value)
     {t.right= insert(x,t.right);}        
   }
     return t;  
  }
  public node remove(int x,node t)
  { 
    if(t==null) {return null;}
    if(xt.value) {t.right=remove(x,t.right);}
    else if(t.left!=null&&t.right!=null)//左右节点均不空
    {
     t.value=findmin(t.right).value;//找到右侧最小值替代
     t.right=remove(t.value,t.right);
    }
    else //左右单空或者左右都空
    {
      if(t.left==null&&t.right==null)
      {t=null;}
      else if(t.right!=null)
      {
        t=t.right;
      }
      else if(t.left!=null)
      {
        t=t.left;
      }
      return t;     
    }   
    return t;   
  }
  public void duilie(node t)
  {
    Queue q1 = new ArrayDeque();
    if(t==null)return;
    if(t!=null) {
    q1.add(t);}
    while(!q1.isEmpty())
    {
      node t1= q1.poll();
      if(t1.left !=null)q1.add(t1.left);
      if(t1.right!=null)q1.add(t1.right);
      System.out.print(t1.value " ");   
    }
    System.out.println();
  }
  public void qianxu(node t)//前序递归 前序遍历:根结点 ---> 左子树 ---> 右子树
  {
    if(t!=null) {
    System.out.print(t.value " ");//当前节点
    qianxu(t.left );
    qianxu(t.right);}   
  }
  public void qianxu2(node t)//非递归前序 栈 先左后右
  {
    Stack q1=new Stack();
    if(t==null)return;
    if(t!=null) {q1.push(t);}         
    while(!q1.empty())
    {
      node t1=q1.pop();         
      if(t1.right!=null) {q1.push(t1.right);}
      if(t1.left!=null) {q1.push(t1.left);}
      System.out.print(t1.value " "); 
    }   
  }
  public void houxu(node t)//后序遍历 后序遍历:左子树 ---> 右子树 ---> 根结点
  {
    if(t!=null)
    {     
      houxu(t.left );
      houxu(t.right);
      System.out.print(t.value " ");  //访问玩左右访问当前节点   
    }       
  }
  public void houxu2(node t)//q1和q2 q1要先右后左,先遍历右侧,q1先装右侧就把右侧放到前面,左侧放在上面(栈顶)
  {
    Stack q1=new Stack();
    Stackq2=new Stack();
    if(t==null)return;
    if(t!=null) {q1.push(t);  }       
    while(!q1.isEmpty())
    {
      node t1=q1.pop();
      q2.push(t1);
      if(t1.left!=null) {q1.push(t1.left);}
      if(t1.right!=null) {q1.push(t1.right);}             
    }
    while(!q2.isEmpty())
    {
      node t1=q2.pop();
      System.out.print(t1.value " ");
    }
  }
  public void zhongxu(node t)//中序遍历 中序遍历:左子树---> 根结点 ---> 右子树
  {
    if(t!=null)
    {
    zhongxu(t.left);
    System.out.print(t.value " ");//访问完左节点访问当前节点
    zhongxu(t.right);
    }
  }
  public void zhongxu2(node t)//先储藏所有左侧点,抛出一个点,访问该点右节点,对右节点在储存所有子左节点
  {
    Stack q1=new Stack();   
    if(t==null)return;    
    if(t!=null) {q1.push(t);}       
    node t1=q1.peek();//不能抛出,要先存最左侧
    while(t1.left!=null)
    {         
      t1=t1.left;
      q1.push(t1);        
    } 
    while(!q1.isEmpty())
    {     
        node t2=q1.pop();
        System.out.print(t2.value " ");
        if(t2.right!=null)  
        {
          t2=t2.right;q1.push(t2);
         while(t2.left!=null)
         {t2=t2.left;
          q1.push(t2);}
        }                       
    }
  }


测试类和数据:


public class exam2 {
  public static void main(String [] args)
  {
    tree a=new tree();    
    a.insert(5, a.root);    
    a.insert(9, a.root);
    a.insert(8, a.root);
    a.insert(4, a.root);
    a.insert(2, a.root);
    a.insert(6, a.root);    
    a.insert(7, a.root);
    a.insert(1, a.root);
    System.out.print("队列遍历");
    a.duilie(a.root);
    System.out.print("前序遍历");
    a.qianxu(a.root);
    System.out.print("非递归前序:");
    a.qianxu2(a.root);
    System.out.println();
    System.out.print("后序遍历");
    a.houxu(a.root);
    System.out.print("非递归后序:");
    a.houxu2(a.root);
    System.out.println();
    System.out.print("中序遍历");   
    a.zhongxu(a.root);    
    System.out.print("非递归中序:");
    a.zhongxu2(a.root);
    System.out.println();
    System.out.println(a.iscontains(12));
    System.out.println(a.iscontains(7));
    System.out.println("min: " a.findmin(a.root).value);
    System.out.println("max: " a.findmax(a.root).value);
    a.remove(9, a.root);
    a.remove(8, a.root);
    System.out.print("前序遍历");
    a.qianxu(a.root);
    System.out.println();
    System.out.print("后序遍历");
    a.houxu(a.root);
    System.out.println();
    System.out.print("中序遍历");
    a.zhongxu(a.root);    
  }
}


结果:


队列遍历5 4 9 2 8 1 6 7

前序遍历5 4 2 1 9 8 6 7 非递归前序:5 4 2 1 9 8 6 7

后序遍历1 2 4 7 6 8 9 5 非递归后序:1 2 4 7 6 8 9 5

中序遍历1 2 4 5 6 7 8 9 非递归中序:1 2 4 5 6 7 8 9

false

true

min: 1

max: 9

前序遍历5 4 2 1 6 7

后序遍历1 2 4 7 6 5

中序遍历1 2 4 5 6 7


不知道还有啥错误的或者不准确的,请大神纠正


目录
相关文章
|
1月前
|
算法 Java
算法:Java计算二叉树从根节点到叶子结点的最大路径和
算法:Java计算二叉树从根节点到叶子结点的最大路径和
|
1月前
|
Java
Java二叉树超详解(常用方法介绍)(2)
Java二叉树超详解(常用方法介绍)(2)
|
1月前
|
存储 Java
JAVA 二叉树超详解(1)
JAVA 二叉树超详解(1)
|
7天前
|
存储 算法 Java
Java中,树与图的算法涉及二叉树的前序、中序、后序遍历以及DFS和BFS搜索。
【6月更文挑战第21天】Java中,树与图的算法涉及二叉树的前序、中序、后序遍历以及DFS和BFS搜索。二叉树遍历通过访问根、左、右子节点实现。DFS采用递归遍历图的节点,而BFS利用队列按层次访问。以下是简化的代码片段:[Java代码略]
16 4
|
1月前
|
Java
Tree Traversals Again(Java语言)(先序和中序创建二叉树)(遍历树)
Tree Traversals Again(Java语言)(先序和中序创建二叉树)(遍历树)
28 4
|
1月前
|
存储 Java
ZigZagging on a Tree二叉树蛇形层次遍历(Java语言)
ZigZagging on a Tree二叉树蛇形层次遍历(Java语言)
23 1
|
1月前
|
存储 Java
Java实现二叉树
Java实现二叉树
28 0
|
6天前
|
Java
Java二叉树的遍历
Java二叉树的遍历
|
11天前
|
算法 Java 索引
【算法】重建二叉树并进行后序遍历的Java实现
【算法】重建二叉树并进行后序遍历的Java实现
18 5
|
9天前
|
算法 搜索推荐 Java
二叉树的基本概念、常见操作以及如何使用Java代码
二叉树的基本概念、常见操作以及如何使用Java代码
10 1