java 实现 创建 二叉树 tree 遍历 二叉树 递归 非递归 先中后序 方式遍历 广度优先

1.data 搞了皮数据

2.实现的tree 结构 

3.弄个tree 节点类

4.java 用array数据实现 linkedlist tree

输出节点内容 这玩意在递归和非递归都用一下

递归手法

飞递归手法

广度优先,深度优先

6.调用

7.日志:

优点

1.data 搞了皮数据
String[] datas = new String[] { "A", "B", "D", "E", "F", "G", "H", "I", "J" };
or

int[] datas = new int[] { 1,2,3,4,5,6,7,8,9};
数据好说之后会把数据放到linklist中

2.实现的tree 结构 就是下边这玩意儿
A
B C
D E F G
H I J
or

    1
 2    3

4 5 6 7
8 9 10
出来的效果就上边这玩意

3.弄个tree 节点类哇
// 节点类
class Node {
String var;// 节点值
Node left;// 左子节点
Node right;// 右子节点

    public Node(String var) {
        this.var = var;
        this.left = null;
        this.right = null;
    }

    public void setLeft(Node left) {
        this.left = left;
    }

    public void setRight(Node right) {
        this.right = right;
    }

    public String getVar() {
        return var;
    }

    public void setVar(String var) {
        this.var = var;
    }

    public Node getLeft() {
        return left;
    }

    public Node getRight() {
        return right;
    }

}

这玩意儿一个是当前节点
一个当前左子节点
一个当前右子节点
主要为了实现一个tree 然后俩个树杈子
添加的时候也是添加一个tree 作为根节点,然后带俩个叉子
有点像迭代子模式,遍历的时候也是递归 or while  循环寻找子叉子出值
 

4.java 用array数据实现 linkedlist tree 
/**

  • @param datas
  • 实现二叉树各节点值的数组
  • @param nodelist
  • 二叉树list
    /
    private void creatBinaryTree(String[] datas, List<Node> nodelist) {
    // 将数组变成node节点
    for (int nodeindex = 0; nodeindex < datas.length; nodeindex++) {// 将数据添加到linklist中
    Node node = new Node(datas[nodeindex]);
    nodelist.add(node);
    }
    // 给所有父节点设定子节点
    for (int index = 0; index < nodelist.size() / 2 - 1; index++) {// 设置父子节点
    // 编号为n的节点他的左子节点编号为2
    n 右子节点编号为2n+1 但是因为list从0开始编号,所以还要+1
    // 这里父节点有1(2,3),2(4,5),3(6,7),4(8,9) 但是最后一个父节点有可能没有右子节点 需要单独处理
    nodelist.get(index).setLeft(nodelist.get(index
    2 + 1));
    nodelist.get(index).setRight(nodelist.get(index 2 + 2));
    }
    // 单独处理最后一个父节点 因为它有可能没有右子节点
    int index = nodelist.size() / 2 - 1;// 弄一下最后一个节点 判断如果是奇数会纯在右子节点,偶数没有
    nodelist.get(index).setLeft(nodelist.get(index
    2 + 1)); // 先设置左子节点
    if (nodelist.size() % 2 == 1) { // 如果有奇数个节点,最后一个父节点才有右子节点
    nodelist.get(index).setRight(nodelist.get(index * 2 + 2));
    }
    }
    这个玩意创建就是把数组中的数据放到linkedlist 中
    linkedlist 作为tree 的样子 
    实现
    1.把节点放入到linkedlist中
    2.把数据左右子放到节点中(这次不放最后一个)
    3.把最后一个坐下判断放入到节点中(这次操作最有一个,应为 最有一个如果是奇数就有俩个叉,偶数一个叉)
     
    输出节点内容 这玩意在递归和非递归都用一下
    /**
  • 遍历当前节点的值
  • @param node
    */
    public void checkCurrentNode(Node node){
    System.out.print(node.getVar()+" ");
    }
    把节点当前内容搞出来
     

递归手法

/**
 * 先序遍历二叉树
 * @param root 二叉树根节点
 */
public void preOrderTraversal(Node node){
    if (node == null)  //很重要,必须加上 当遇到叶子节点用来停止向下遍历
        return;  
    checkCurrentNode(node);
    preOrderTraversal(node.getLeft());
    preOrderTraversal(node.getRight());
}
/**
 * 中序遍历二叉树
 * @param root 根节点
 */
public void inOrderTraversal(Node node){
    if (node == null)  //很重要,必须加上
        return;  
    inOrderTraversal(node.getLeft());
    checkCurrentNode(node);
    inOrderTraversal(node.getRight());
}
/**
 * 后序遍历二叉树
 * @param root 根节点
 */
public void postOrderTraversal(Node node){
    if (node == null)  //很重要,必须加上
        return;  
    postOrderTraversal(node.getLeft());
    postOrderTraversal(node.getRight());
    checkCurrentNode(node);
}

对输出的时候做点手法

在递归节点内容的前后改一下就实现了前中后遍历的手法

飞递归手法
/**

  • 非递归前序遍历
  • @param node
    */
    public void preOrderTraversalbyLoop(Node node){
    Stack<Node> stack = new Stack();
    Node p = node;
    while(p!=null || !stack.isEmpty()){
    while(p!=null){ //当p不为空时,就读取p的值,并不断更新p为其左子节点,即不断读取左子节点
    checkCurrentNode(p);
    stack.push(p); //将p入栈
    p = p.getLeft();
    }
    if(!stack.isEmpty()){
    p = stack.pop();
    p = p.getRight();
    }
    }
    }
    /**
  • 非递归中序遍历
  • @param node
    */
    public void inOrderTraversalbyLoop(Node node){
    Stack<Node> stack = new Stack();
    Node p = node;
    while(p!=null || !stack.isEmpty()){
    while(p!=null){
    stack.push(p);
    p = p.getLeft();
    }
    if(!stack.isEmpty()){
    p = stack.pop();
    checkCurrentNode(p);
    p = p.getRight();
    }
    }
    }
    /**
  • 非递归后序遍历
  • @param node
    */
    public void postOrderTraversalbyLoop(Node node){
    Stack<Node> stack = new Stack<>();
    Node p = node,prev = node;
    while(p!=null || !stack.isEmpty()){
    while(p!=null){
    stack.push(p);
    p = p.getLeft();
    }
    if(!stack.isEmpty()){
    Node temp = stack.peek().getRight();
    if(temp == null||temp == prev){
    p = stack.pop();
    checkCurrentNode(p);
    prev = p;
    p = null;
    }else{
    p = temp;
    }
    }
    }
    }
     
    广度优先,深度优先

    /**

  • 广度优先遍历(从上到下遍历二叉树)
  • @param root
    */
    public void bfs(Node root){
    if(root == null) return;
    LinkedList<Node> queue = new LinkedList<Node>();
    queue.offer(root); //首先将根节点存入队列
    //当队列里有值时,每次取出队首的node打印,打印之后判断node是否有子节点,若有,则将子节点加入队列
    while(queue.size() > 0){
    Node node = queue.peek();
    queue.poll(); //取出队首元素并打印
    System.out.print(node.var+" ");
    if(node.left != null){ //如果有左子节点,则将其存入队列
    queue.offer(node.left);
    }
    if(node.right != null){ //如果有右子节点,则将其存入队列
    queue.offer(node.right);
    }
    }
    }
    /**
  • 深度优先遍历
  • @param node
  • @param rst
  • @param list
    /
    public void dfs(Node node,List<List<Integer>> rst,List<Integer> list){
    if(node == null) return;
    if(node.left == null && node.right == null){
    list.add(node.var);
    /
    这里将list存入rst中时,不能直接将list存入,而是通过新建一个list来实现,
    • 因为如果直接用list的话,后面remove的时候也会将其最后一个存的节点删掉*/
      rst.add(new ArrayList<>(list));
      list.remove(list.size()-1);
      }
      list.add(node.var);
      dfs(node.left,rst,list);
      dfs(node.right,rst,list);
      list.remove(list.size()-1);
      }
      广度优先遍历:
      A B D E F G H I J 
      深度优先遍历:
      [[A, B, E, I], [A, B, E, J], [A, B, F], [A, D, G], [A, D, H]]

6.调用
public static void main(String[] args) {
RCSTest tree = new RCSTest();
String[] datas = new String[]{"A","B","D","E","F","G","H","I","J"};
List<Node> nodelist = new LinkedList<>();
tree.creatBinaryTree(datas, nodelist);
Node root = nodelist.get(0);
System.out.println("递归先序遍历:");
tree.preOrderTraversal(root);
System.out.println();
System.out.println("非递归先序遍历:");
tree.preOrderTraversalbyLoop(root);
System.out.println();
System.out.println("递归中序遍历:");
tree.inOrderTraversal(root);
System.out.println();
System.out.println("非递归中序遍历:");
tree.inOrderTraversalbyLoop(root);
System.out.println();
System.out.println("递归后序遍历:");
tree.postOrderTraversal(root);
System.out.println();
System.out.println("非递归后序遍历:");
tree.postOrderTraversalbyLoop(root);
System.out.println();
System.out.println("广度优先遍历:");
tree.bfs(root);
System.out.println();
System.out.println("深度优先遍历:");
List<List<String>> rst = new ArrayList<>();
List<String> list = new ArrayList<>();
tree.dfs(root,rst,list);
System.out.println(rst);
}
 

7.日志:
递归先序遍历:
A B E I J F D G H
非递归先序遍历:
A B E I J F D G H
递归中序遍历:
I E J B F A G D H
非递归中序遍历:
I E J B F A G D H
递归后序遍历:
I J E F B G H D A
非递归后序遍历:
I J E F B G H D A
广度优先遍历:
A B D E F G H I J
深度优先遍历:
[[A, B, E, I], [A, B, E, J], [A, B, F], [A, D, G], [A, D, H]]
or

递归先序遍历:
1 2 4 8 9 5 3 6 7
非递归先序遍历:
1 2 4 8 9 5 3 6 7
递归中序遍历:
8 4 9 2 5 1 6 3 7
非递归中序遍历:
8 4 9 2 5 1 6 3 7
递归后序遍历:
8 9 4 5 2 6 7 3 1
非递归后序遍历:
8 9 4 5 2 6 7 3 1
广度优先遍历:
1 2 3 4 5 6 7 8 9
深度优先遍历:
[[1, 2, 4, 8], [1, 2, 4, 9], [1, 2, 5], [1, 3, 6], [1, 3, 7]]
将数据重String 缓存 int 
 

优点
二叉树优点在于,二叉树在做大数据的时候,相对于传统的规范序列性能好,应为他不需要查询全部即可获得信息or修改也是,这样就可以减少全数据的检索和操作从而大大提升效率,但小数据意义就不是很容易开出来,比如有2000万个32位的string数据,我们要干点啥如果用传统的一个一个检索操作,就可思考出消耗情况了。

ok

持续更新


作者:宇神城主
来源:CSDN
原文:https://blog.csdn.net/weixin_42749765/article/details/94737141
版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.51cto.com/11719289/2421263