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

一 前言

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

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

前序遍历:就是先遍历当前节点,再遍历左子树,最后遍历右子树   中左右  对于下图  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("层次遍历");

    }
}

  

猜你喜欢

转载自www.cnblogs.com/caijiwdq/p/11024890.html
今日推荐