• 算法与数据结构 (二) 二叉树的简单实现,非递归的前序遍历 中序遍历 后序遍历


    一 前言

    树是一种逻辑结构,物理实现有连续存储方式(数组)和非连续的链表方式。最常见的是二叉树,连续存储就是按照层次遍历的方法,依次存入数组,但空的节点也必须存储,也就是说会造成空间的浪费 ,所以只适用于满二叉树和完全二叉树。

    树的遍历方法 有两类,一类是深度遍历:

    前序遍历:就是先遍历当前节点,再遍历左子树,最后遍历右子树   中左右  对于下图  80 55 32 60 90 96 98

    中序遍历:对应的就是  左中右   32 55 60 80 90 96 98

    后序遍历: 左右中       32 60 55 98 96 90 80

    另一类是层次遍历 

    就是按层访问  80  55 90 32 60 96 98

     对于第一类深度优先,是一个递归的过程,所以用递归的算法很容易。而非递归在于自己手动创建栈,实现递归过程。

    二 代码实现

    二叉树的遍历首先是要有一棵树,在漫画算法里有一个基于链表创建二叉树的例子。见代码:(另外要用数组描述二叉树,有两种方式,一是给出中序遍历和其它先(后)序遍历,或者就是带空节点的遍历方法 比如上图的遍历就是

    {80, 55, 32, null, null, 60, null, null, 90, null, 96,null,98,null,null}

     下面的算法就是基于这样的链表实现二叉树的创建的

    package tree;
    
    import java.util.*;
    
    public class MyTree {
    
        int val;
        MyTree left;
        MyTree right;
    
        MyTree() {
        }
    
        MyTree(int val) {
            this.val = val;
    
        }  //二叉树结构定义
    
    //根据链表创建二叉树
        public static MyTree createTree(LinkedList<Integer> list) {
            if (list == null || list.size() == 0)
                return null;
            Integer data = list.removeFirst();
            MyTree node = null;
            if (data != null) {
                node = new MyTree(data);
                node.left = createTree(list);
                node.right = createTree(list);
            }
            return node;
        }
    //前序遍历的递归版本
        public static void xianXu(MyTree tree) {
            if (tree == null)
                return;
            System.out.print(tree.val + " ");
            xianXu(tree.left);
            xianXu(tree.right);
        }
    //中序遍历的递归版本
        public static void zhongXu(MyTree tree) {
            if (tree == null)
                return;
            zhongXu(tree.left);
            System.out.print(tree.val + " ");
            zhongXu(tree.right);
        }
    //后序遍历的递归版本
        public static void houXu(MyTree tree) {
            if (tree == null)
                return;
            houXu(tree.left);
            houXu(tree.right);
            System.out.print(tree.val + " ");
        }
    //先序遍历的非递归版本
        public static void xianXu1(MyTree tree) {
            if (tree == null)
                return;
            Deque<MyTree> deque = new ArrayDeque<>();
            MyTree node = null;
            deque.push(tree);
            while (!deque.isEmpty()) {
                node = deque.pop();
                System.out.print(node.val + " ");
                if (node.right != null)
                    deque.push(node.right);
                if (node.left != null)
                    deque.push(node.left);
    
            }
        }
    //中序遍历的非递归版本
        public static void zhongXu1(MyTree tree) {
            if (tree == null) {
                return;
            }
            MyTree now = tree;
            Deque<MyTree> deque = new ArrayDeque<>();
            while (!deque.isEmpty() || now != null) {
                while (now != null) {
                    deque.push(now);
                    now = now.left;
                }
                now = deque.pop();
                System.out.print(now.val + " ");
                now = now.right;
            }
        }
    //后序遍历的非递归版本
        public static void houXu1(MyTree tree) {
            if (tree == null)
                return;
            Deque<MyTree> deque = new ArrayDeque<>();
            Deque<Integer> deque1 = new ArrayDeque<>();
    
            MyTree node = null;
            deque.push(tree);
            while (!deque.isEmpty()) {
                node = deque.pop();
                deque1.push(node.val);
                if (node.left != null)
                    deque.push(node.left);
                if (node.right != null)
                    deque.push(node.right);
    
            }
            while (!deque1.isEmpty())
                System.out.print(deque1.pop() + " ");
        }
    //层次遍历
        public static void cengCi(MyTree tree) {
            if (tree == null)
                return;
            Queue<MyTree> queue = new ArrayDeque<>();
            MyTree now = null;
            queue.offer(tree);
            while (!queue.isEmpty()) {
                now = queue.poll();
                System.out.print(now.val + " ");
                if (now.left != null)
                    queue.offer(now.left);
                if (now.right != null)
                    queue.offer(now.right);
            }
        }
    }
    

      下面是测试代码:

    public class TreeTest {
        public static void main(String[] args) {
            Integer[] arr = {80, 55, 32, null, null, 60, null, null, 90, null, 96,null,98,null,null};
            MyTree tree=MyTree.createTree(new LinkedList<>(Arrays.asList(arr)));
            MyTree.xianXu(tree);
            System.out.println("前序递归");
            MyTree.xianXu1(tree);
            System.out.println("前序非递归");
            MyTree.zhongXu(tree);
            System.out.println("中序递归");
            MyTree.zhongXu1(tree);
            System.out.println("中序非递归");
            MyTree.houXu(tree);
            System.out.println("后序递归");
            MyTree.houXu1(tree);
            System.out.println("后序非递归");
            MyTree.cengCi(tree);
            System.out.println("层次遍历");
    
        }
    }
    

      

  • 相关阅读:
    Visual studio 2010 OpenGL配置
    OPENSTACK在RHEL7安装;admin创建虚拟机模板供demo使用
    hdu 1856 More is better
    AJAX基础知识点学习
    socket.io+angular.js+express.js做个聊天应用(三)
    Java中的继承
    00078_迭代器
    马尔可夫不等式与切比雪夫不等式
    特征值与特征向量
    人工智能数学参考---4、SVD矩阵分解 注意
  • 原文地址:https://www.cnblogs.com/caijiwdq/p/11024890.html
Copyright © 2020-2023  润新知