递归遍历各种数据结构,深入理解前序遍历,后续遍历,深度优先dfs。

一.递归遍历数组

public class Graph4Test {    public static void main(String[] args) {        int[] a1 = new int[]{1,2,3,4,5,6};        preOrder(a1,0);        System.out.println();        postOrder(a1,0);    }  //前序遍历    private static void preOrder(int[] a,int pos) {    //递归退出条件 ,即当前索引下标值 > 数组的length        if(a.length-1<pos){            return;        }        System.out.print(a[pos] ",");        preOrder(a,pos 1);    }  //后续遍历    private static void postOrder(int[] a,int pos) {        if(a.length-1<pos){            return;        }        postOrder(a,pos 1);        System.out.print(a[pos] ",");    }}

输出:

1,2,3,4,5,6,
6,5,4,3,2,1,

前序遍历调用

后序遍历调用,后序遍历的话,是先一直递归查找到最后一个元素,才开始调用打印,所以是从后往前打印

.递归遍历链表

链表的递归遍历同数组的一样

public class ListTest1 {    public static void main(String[] args) {        ListNode l1 = LinkListUtil.geneLinkList(new int[]{1,2,3,4,5,6});        preOrder(l1);        System.out.println();        postOrder(l1);    }//前序遍历    private static void preOrder(ListNode l){//递归的退出条件,指向链表的当前指针为空        if(l==null){            return;        }        System.out.print(l.getVal() ",");        preOrder(l.getNext());    }//后序遍历    private static void postOrder(ListNode l){        if(l==null){            return;        }        postOrder(l.getNext());        System.out.print(l.getVal() ",");    }}

输出:

1,2,3,4,5,6,
6,5,4,3,2,1,

三.递归遍历二叉树

public class BTTest2 {    public static void main(String[] args) {        TreeNode n1 = BTUtils.generateTreeNode(new Integer[]{1,2,3,4,null,5,6});        preOrder(n1);        System.out.println();        postOrder(n1);    }//前序遍历    private static void preOrder(TreeNode root){        if(root==null){            return;        }        System.out.print(root.getVal() ",");        preOrder(root.getLeft());        preOrder(root.getRight());    }//后序遍历    private static void postOrder(TreeNode root){        if(root==null){            return;        }        preOrder(root.getLeft());        preOrder(root.getRight());        System.out.print(root.getVal() ",");    }}

输出:

1,2,4,3,5,6,
4,2,5,6,3,1,

前序遍历调用过程

后序遍历调用过程

四.递归遍历多叉树,森林

前序遍历

public class NTreeTest1{    public static void main(String[] args) {        Node r1 = new Node(1);        Node r21 = new Node(3);        Node r22 = new Node(2);        Node r23 = new Node(4);        Node r31 = new Node(5);        Node r32 = new Node(6);        r21.children.add(r31);        r21.children.add(r32);        r1.children.add(r21);        r1.children.add(r22);        r1.children.add(r23);        List<Integer> preorder = preorder(r1);        ArrayUtils.displayArray(preorder);    }    public static List<Integer> preorder(Node root) {        List<Integer> list = new ArrayList<>();        preorder(root,list);        return list;    }    private static void preorder(Node root,List<Integer> list){        if(root==null){            return;        }        list.add(root.val);        for (int i = 0; i < root.children.size(); i  ) {            preorder(root.children.get(i),list);        }    }}

输出: [1,3,5,6,2,4]

后序遍历

public class NTreeTest2{    public static void main(String[] args) {        Node r1 = new Node(1);        Node r21 = new Node(3);        Node r22 = new Node(2);        Node r23 = new Node(4);        Node r31 = new Node(5);        Node r32 = new Node(6);        r21.children.add(r31);        r21.children.add(r32);        r1.children.add(r21);        r1.children.add(r22);        r1.children.add(r23);        List<Integer> preorder = postorder(r1);        ArrayUtils.displayArray(preorder);    }    public static List<Integer> postorder(Node root) {        List<Integer> list = new ArrayList<>();        postorder(root,list);        return list;    }    private static void postorder(Node root,List<Integer> list){        if(root==null){            return;        }        for (int i = 0; i < root.children.size(); i  ) {            postorder(root.children.get(i),list);        }        list.add(root.val);    }}

输出 : [5,6,3,2,4,1]

思路和二叉树一样 ,只是把二叉树的 root.left 和root.right  改成  for循环遍历 root.children罢了.

五.递归遍历图,深度优先遍历 dfs

test1方法的图 ,和多叉树一样                      邻接表

test2方法的图                                                     邻接表

graph.java

因为图可能带环,所以用一个 Set<T> visited  来保存遍历过的图节点

public class Graph<T> {//邻接表,这里用一个hashMap 来实现    private Map<T,LinkedList<T>> adj = new HashMap<>();    public void addEdge(T begin, T end)    {       if(!adj.containsKey(begin)){           adj.put(begin,new LinkedList<T>());       }        if(!adj.containsKey(end)){            adj.put(end,new LinkedList<T>());        }        adj.get(begin).addLast(end);        adj.get(end).addLast(begin);    }    private void dfs(T v, Set<T> visited)    {       //或者在这里加上递归退出条件,该节点遍历过就退出    //if(visited.contains(v){    //return;       //}        visited.add(v);        System.out.print(v   " ");        LinkedList<T> linkedList = adj.get(v);        //找邻接表的元素,从第一个元素开始找,一直找节点的邻接表的第一个,找到没有位置,或者遍历过位置        for (T t : linkedList) {            if (!visited.contains(t)){                dfs(t, visited);            }        }    }    public void dfs(T v)    {        Set<T> visited = new HashSet<>();        dfs(v, visited);    }}
GraphNode.java
public class GraphNode {    private int val;    public GraphNode(int val) {        this.val = val;    }    public int getVal() {        return val;    }    public void setVal(int val) {        this.val = val;    }    @Override    public String toString() {        return "GraphNode{"                  "val="   val                  '}';    }    @Override    public boolean equals(Object o) {        if (this == o) return true;        if (o == null || getClass() != o.getClass()) return false;        GraphNode graphNode = (GraphNode) o;        return val == graphNode.val;    }    @Override    public int hashCode() {        return Objects.hash(val);    }}
Graph3Test.java
public class Graph3Test {    public static void main(String[] args) {        test1();        System.out.println();        test2();    }    private static void test1(){        Graph<GraphNode> graph = new Graph<>();        GraphNode n1 = new GraphNode(1);        GraphNode n2 = new GraphNode(2);        GraphNode n3 = new GraphNode(3);        GraphNode n4 = new GraphNode(4);        graph.addEdge(n1,n2);        graph.addEdge(n1,n3);        graph.addEdge(n1,n4);        graph.dfs(n1);    }    private static void test2(){        Graph<GraphNode> graph = new Graph<>();        GraphNode n1 = new GraphNode(1);        GraphNode n2 = new GraphNode(2);        GraphNode n3 = new GraphNode(3);        GraphNode n4 = new GraphNode(4);        GraphNode n5 = new GraphNode(5);        graph.addEdge(n1,n2);        graph.addEdge(n1,n3);        graph.addEdge(n1,n4);        graph.addEdge(n2,n5);        graph.addEdge(n2,n4);        graph.dfs(n1);    }}

输出:

GraphNode{val=1} GraphNode{val=2} GraphNode{val=3} GraphNode{val=4}
GraphNode{val=1} GraphNode{val=2} GraphNode{val=5} GraphNode{val=4} GraphNode{val=3}

test1 的调用过程

test2 的调用过程

来源:https://www.icode9.com/content-4-823001.html

(0)

相关推荐

  • (1条消息) 万字长文!二叉树入门和刷题看这篇就够了!

    今天是小浩算法 "365刷题计划" 二叉树入门 - 整合篇.本篇作为入门整合篇,已经砍去难度较大的知识点,所有列出的内容,均为必须掌握.因为很长,写下目录: 二叉树是啥 二叉树的最 ...

  • python经典趣味24点游戏程序设计

    一.游戏玩法介绍: 24点游戏是儿时玩的主要益智类游戏之一,玩法为:从一副扑克中抽取4张牌,对4张牌使用加减乘除中的任何方法,使计算结果为24.例如,2,3,4,6,通过( ( ( 4 + 6 ) - ...

  • 写给小白看的递归(硬核)

    来源丨经授权转自 bigsai(ID:bigsai) 大家好,我是bigsai,之前有老弟说弄不懂递归,今天给大家讲讲递归. 什么是递归? 递归:就是函数自己调用自己.子问题须与原始问题为同样的事,或 ...

  • 数据结构—树|二叉树|前序遍历、中序遍历、后序遍历【图解实现】

    AI研习图书馆,发现不一样的精彩世界 数据 结构 二叉树的遍历 一.树 在谈二叉树的知识点之前,我们首先来看一下树和图的基本概念. 树:不包含回路的连通无向图,树是一种简单的非线性结构. 由于树有一个 ...

  • Java,数据结构和算法,八大数据结构,链表的操作及遍历排序

    IT小奋斗2021-02-13 09:32:51 链表 链表:一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的. 单向链表:只有一个指向下一个节点的指针( ...

  • 五分钟让你彻底理解二叉树的非递归遍历

    什么是二叉树 在计算机科学中二叉树,binary tree,是一种数据结构,在该数据结构中每个节点最多有两个子节点,如图所示: 二叉树的定义就是这样简单,但这种看起来很简单的数据结构遍历起来一点都不简 ...

  • 二叉树的前序遍历的非递归实现

    我们知道二叉树的遍历主要有,前序,中序,后续,我们常用递归的方式进行实现,而我们都知道能用递归函数实现,都可以用数据结构栈进行实现. 下面我们就用栈的数据结构来处理二叉树的前序遍历: BinaryTr ...

  • ​LeetCode刷题实战255:验证前序遍历序列二叉搜索树

    算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试.所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 ! 今天和大家 ...

  • Perl篇:递归遍历及拷贝文件共享服务器中目录

    关于Perl递归遍历目录的文章其实很多,但是大多数都是针对本地机器磁盘间的操作,如将C盘根目录下的A文件夹整个拷贝到D盘根目录下的A文件夹.但是,对于将一个局域网内其他机器开放的文件共享目录递归遍历或 ...

  • 数据结构—二叉树的遍历及重构二叉树【图示详解】

    AI研习图书馆,发现不一样的精彩世界 数据 结构 二叉树的遍历 之前的一篇文章:数据结构-树|二叉树|前序遍历.中序遍历.后序遍历[图解实现],只对二叉树的遍历进行了宽泛的描述,这篇随笔重点对二叉树的 ...

  • java实现二叉树的遍历(递归和非递归)

    源码地址: https://github.com/TimePickerWang/aimed-at-offer/blob/master/java%E6%BA%90%E7%A0%81/TreeInfo.j ...

  • PHP数据结构-二叉树的遍历及逻辑操作

    二叉树的遍历及逻辑操作 上篇文章我们讲了许多理论方面的知识,虽说很枯燥,但那些都是我们今天学习的前提,一会看代码的时候你就会发现这些理论知识是多么地重要了.首先,我们还是要说明一下,我们学习的主要内容 ...