数据结构与算法之树的入门(二叉树)(三)

简介: 数据结构与算法之树的入门(二叉树)

七、二叉树的最大深度问题


需求:


给定一棵树,请计算树的最大深度(树的根节点到最远叶子结点的最长路径上的结点数)


add2332a8c1d4ec785e78a2e431535eb.png

上面这棵树的最大深度为4。


实现:


我们在1.4中创建的树上,添加如下的API求最大深度:


public int maxDepth() :计算整个树的最大深度


private int maxDepth(Node x): 计算指定树x的最大深度


实现步骤


1.如果根结点为空,则最大深度为0;


2.计算左子树的最大深度;

3.计算右子树的最大深度;

4.当前树的最大深度=左子树的最大深度和右子树的最大深度中的较大者+1


代码:

// 计算整个树的最大深度
public int maxDepth() {
  return maxDepth(root);
}
//计算指定树x的最大深度
private int maxDepth(Node x) {
  //1.如果根结点为空,则最大深度为0;
  if (x == null) {
    return 0;
  }
  int max = 0;
  int maxL = 0;
  int maxR = 0;
  //2.计算左子树的最大深度;
  if (x.left != null) {
    maxL = maxDepth(x.left);
  }
  //3.计算右子树的最大深度;
  if (x.right != null) {
    maxR = maxDepth(x.right);
  }
  //4.当前树的最大深度=左子树的最大深度和右子树的最大深度中的较大者+1
  max = maxL > maxR ? maxL + 1 : maxR + 1;
  return max;
}
//测试代码
public class Test {
  public static void main(String[] args) throws Exception {
    BinaryTree<String, String> bt = new BinaryTree<>();
    bt.put("E", "5");
    bt.put("B", "2");
    bt.put("G", "7");
    bt.put("A", "1");
    bt.put("D", "4");
    bt.put("F", "6");
    bt.put("H", "8");
    bt.put("C", "3");
    int i = bt.maxDepth();
    System.out.println(i);
  }
}

八、折纸问题


需求:


请把一段纸条竖着放在桌子上,然后从纸条的下边向上方对折1次,压出折痕后展开。此时 折痕是凹下去的,即折痕突起的方向指向纸条的背面。如果从纸条的下边向上方连续对折2 次,压出折痕后展开,此时有三条折痕,从上到下依次是下折痕、下折痕和上折痕。


给定一 个输入参数N,代表纸条都从下边向上方连续对折N次,请从上到下打印所有折痕的方向 例如:N=1时,打印: down;N=2时,打印: down down up


9a57d8fe8c3142d58b574f5d2a4dea6f.png

分析:


我们把对折后的纸张翻过来,让粉色朝下,这时把第一次对折产生的折痕看做是根结点,那第二次对折产生的下折痕就是该结点的左子结点,而第二次对折产生的上折痕就是该结点的右子结点,这样我们就可以使用树型数据结构来描述对折后产生的折痕。


这棵树有这样的特点:


1.根结点为下折痕;

2.每一个结点的左子结点为下折痕;

3.每一个结点的右子结点为上折痕;


8ed42df6b08b455fb226331add2ddaf0.png

实现步骤:


1.定义结点类

2.构建深度为N的折痕树;

3.使用中序遍历,打印出树中所有结点的内容;


构建深度为N的折痕树:


1.第一次对折,只有一条折痕,创建根结点;

2.如果不是第一次对折,则使用队列保存根结点;

3.循环遍历队列:

3.1从队列中拿出一个结点;

3.2如果这个结点的左子结点不为空,则把这个左子结点添加到队列中;

3.3如果这个结点的右子结点不为空,则把这个右子结点添加到队列中;

3.4判断当前结点的左子结点和右子结点都不为空,如果是,则需要为当前结点创建一个值为down的左子结点,一个值为up的右子结点。


代码:


public class PaperFolding {
  public static void main(String[] args) {
    //构建折痕树
    Node tree = createTree(3);
    //遍历折痕树,并打印
    printTree(tree);
  }
  //3.使用中序遍历,打印出树中所有结点的内容;
  private static void printTree(Node tree) {
    if (tree==null){
      return;
    }
    printTree(tree.left);
    System.out.print(tree.item+",");
    printTree(tree.right);
  }
  //2.构建深度为N的折痕树;
  private static Node createTree(int N) {
      Node root = null;
    for (int i = 0; i <N ; i++) {
      if (i==0){
        //1.第一次对折,只有一条折痕,创建根结点;
        root = new Node("down",null,null);
      }else{
        //2.如果不是第一次对折,则使用队列保存根结点;
        Queue<Node> queue = new Queue<>();
        queue.enqueue(root);
        //3.循环遍历队列:
        while(!queue.isEmpty()){
          //3.1从队列中拿出一个结点;
          Node tmp = queue.dequeue();
          //3.2如果这个结点的左子结点不为空,则把这个左子结点添加到队列中;
          if (tmp.left!=null){
            queue.enqueue(tmp.left);
          }
          //3.3如果这个结点的右子结点不为空,则把这个右子结点添加到队列中;
          if (tmp.right!=null){
            queue.enqueue(tmp.right);
          }
          //3.4判断当前结点的左子结点和右子结点都不为空,如果是,则需要为当前结点创建一个值为down的左子结点,一个值为up的右子结点。
          if (tmp.left==null && tmp.right==null){
            tmp.left = new Node("down",null,null);
            tmp.right = new Node("up",null,null);
          }
        }
      }
    }
    return root;
  }
  //1.定义结点类
  private static class Node{
    //存储结点元素
    String item;
    //左子结点
    Node left;
    //右子结点
    Node right;
    public Node(String item, Node left, Node right) {
      this.item = item;
      this.left = left;
      this.right = right;
    }
  }
}


目录
相关文章
|
1月前
|
算法
数据结构之博弈树搜索(深度优先搜索)
本文介绍了使用深度优先搜索(DFS)算法在二叉树中执行遍历及构建链表的过程。首先定义了二叉树节点`TreeNode`和链表节点`ListNode`的结构体。通过递归函数`dfs`实现了二叉树的深度优先遍历,按预序(根、左、右)输出节点值。接着,通过`buildLinkedList`函数根据DFS遍历的顺序构建了一个单链表,展示了如何将树结构转换为线性结构。最后,讨论了此算法的优点,如实现简单和内存效率高,同时也指出了潜在的内存管理问题,并分析了算法的时间复杂度。
52 0
|
1天前
|
存储 算法 Python
文件管理系统中基于 Python 语言的二叉树查找算法探秘
在数字化时代,文件管理系统至关重要。本文探讨了二叉树查找算法在文件管理中的应用,并通过Python代码展示了其实现过程。二叉树是一种非线性数据结构,每个节点最多有两个子节点。通过文件名的字典序构建和查找二叉树,能高效地管理和检索文件。相较于顺序查找,二叉树查找每次比较可排除一半子树,极大提升了查找效率,尤其适用于海量文件管理。Python代码示例包括定义节点类、插入和查找函数,展示了如何快速定位目标文件。二叉树查找算法为文件管理系统的优化提供了有效途径。
33 5
|
27天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
53 5
|
1月前
|
算法
分享一些提高二叉树遍历算法效率的代码示例
这只是简单的示例代码,实际应用中可能还需要根据具体需求进行更多的优化和处理。你可以根据自己的需求对代码进行修改和扩展。
|
1月前
|
存储 缓存 算法
如何提高二叉树遍历算法的效率?
选择合适的遍历算法,如按层次遍历树时使用广度优先搜索(BFS),中序遍历二叉搜索树以获得有序序列。优化数据结构,如使用线索二叉树减少空指针判断,自定义节点类增加辅助信息。利用递归与非递归的特点,避免栈溢出问题。多线程并行遍历提高速度,注意线程安全。缓存中间结果,避免重复计算。预先计算并存储信息,提高遍历效率。综合运用这些方法,提高二叉树遍历算法的效率。
60 5
|
1月前
|
机器学习/深度学习 JSON 算法
二叉树遍历算法的应用场景有哪些?
【10月更文挑战第29天】二叉树遍历算法作为一种基础而重要的算法,在许多领域都有着不可或缺的应用,它为解决各种复杂的问题提供了有效的手段和思路。随着计算机科学的不断发展,二叉树遍历算法也在不断地被优化和扩展,以适应新的应用场景和需求。
47 0
|
1月前
|
算法
数据结构之文件系统模拟(树数据结构)
本文介绍了文件系统模拟及其核心概念,包括树状数据结构、节点结构、文件系统类和相关操作。通过构建虚拟环境,模拟文件的创建、删除、移动、搜索等操作,展示了文件系统的基本功能和性能。代码示例演示了这些操作的具体实现,包括文件和目录的创建、移动和删除。文章还讨论了该算法的优势和局限性,如灵活性高但节点移除效率低等问题。
53 0
|
1月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
208 9
|
1月前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
35 1
|
1月前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。