0
点赞
收藏
分享

微信扫一扫

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

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

如果对后端、爬虫等感性趣欢迎关注我的个人公众号交流:​​bigsai​


举报

相关推荐

0 条评论