设为首页 加入收藏

TOP

二叉树(binary tree)(一)
2023-09-23 15:44:37 】 浏览:235
Tags:binary tree

二叉树(binary tree)

二叉树(Binary Tree)是一种常见的树状数据结构,它由一组节点组成,每个节点最多有两个子节点,分别称为左子节点和右子节点。二叉树具有以下特点:

  1. 每个节点最多有两个子节点,分别称为左子节点和右子节点。
  2. 左子树和右子树也是二叉树,它们的结构与父节点类似。
  3. 二叉树的顺序不固定,可以是任意形状。

两种特殊形式

二叉树还有两种特殊形式,一个叫作满二叉树 ,另一个叫作完全二叉树

满二叉树

如果该二叉树的所有叶子节点都在最后一层,并且结点总数= 2^n -1,n 为层数,则我们称为满二又树。简单点说,满二叉树的每一个分支都是满的。

完全二叉树

对一个有n个节点的二叉树,按层级顺序编号,则所有节点的编号为从1到n。如果这个树所有节点和同样深度的满二叉树的编号为从1到n的节点位置相同,则这个二叉树为完全二叉树。完全二叉树的条件没有满二叉树那么苛刻: 满二叉树要求所有分支都是满的;而完全二叉树只需保证最后一个节点之前的节点都齐全即可。

遍历二叉树

在计算机程序中,遍历本身是一个线性操作。所以遍历同样具有线性结构的数组或链表,是一件轻而易举的事情。反观二叉树,是典型的非线性数据结构,遍历时需要把非线性关联的点转化成一个线性的序列,以不同的方式来遍历,遍历出的序列顺序也不同。

遍历方式

深度优先和广度优先这两个概念不止局限于二叉树,它们更是一种抽象的算法思想,决定了访问某些复杂数据结构的顺序。在访问树、图,或其他一些复杂数据结构时,这两个概念常常被使用到。

1.深度优先遍历(Depth-First Search,DFS)

所谓深度优先,顾名思义,就是偏向于纵深,“一头扎到底”的访问方式。可能这种说法有些抽象,下面就通过二叉树的前序遍历、中序遍历、后序遍历 ,来看一看深度优先

2.广度优先遍历 (Breadth-First Search,BFS)

如果说深度优先遍历是在一个方向上“一头扎到底”,那么广度优先遍历则恰恰相反:先在各个方向上各走出1步,再在各个方向上走出第2步、第3步......一直到各个方向全部走完。听起来有些抽象,下面让我们通过二叉树的层序遍历

也是一种遍历或搜索树或图的算法。在广度优先遍历中,从根节点开始,按照层级顺序逐层访问节点,先访问当前层的所有节点,然后再访问下一层的节点。广度优先遍历可以使用队列来实现。

前序遍历

根节点 -> 左子树 -> 右子树。在前序遍历中,首先访问根节点,然后按照左子树和右子树的顺序递归地进行前序遍历。

    // 前序遍历二叉树(根-左-右)
    public static void preOrderTraversal(TreeNode node) {
        if (node == null) {
            return;
        }

        System.out.print(node.val + " ");

        preOrderTraversal(node.left);
        preOrderTraversal(node.right);
    }

中序遍历

左子树 -> 根节点 -> 右子树。在中序遍历中,首先按照左子树的顺序递归地进行中序遍历,然后访问根节点,最后按照右子树的顺序递归地进行中序遍历。

    // 中序遍历二叉树(左-根-右)
    public static void inOrderTraversal(TreeNode node) {
        if (node == null) {
            return;
        }

        inOrderTraversal(node.left);

        System.out.print(node.val + " ");

        inOrderTraversal(node.right);
    }

后序遍历

左子树 -> 右子树 -> 根节点。在后序遍历中,首先按照左子树和右子树的顺序递归地进行后序遍历,然后访问根节点。

    // 后序遍历二叉树(左-右-根)
    public static void postOrderTraversal(TreeNode node) {
        if (node == null) {
            return;
        }

        postOrderTraversal(node.left);
        postOrderTraversal(node.right);

        System.out.print(node.val + " ");
    }
 public static void main(String[] args) {
        // 创建一个二叉树
        TreeNode root = new TreeNode(1);
        root.left = new TreeNode(2);
        root.right = new TreeNode(3);
        root.left.left = new TreeNode(4);
        root.left.right = new TreeNode(5);

        // 前序遍历二叉树
        System.out.println("前序遍历结果:");
        preOrderTraversal(root);

        // 中序遍历二叉树
        System.out.println("\n中序遍历结果:");
        inOrderTraversal(root);

        // 后序遍历二叉树
        System.out.println("\n后序遍历结果:");
        postOrderTraversal(root);
    }

层次遍历

是一种广度优先遍历的应用,它按照层级顺序逐层访问二叉树的节点。在层次遍历中,从根节点开始,先访问根节点,然后按照从左到右的顺序逐层访问每个节点的子节点,一层一层横向遍历各个节点,可以借助于队列实现。

public static void levelOrderTraversal(TreeNode root) {
    if (root == null) {
        return;
    }
    
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root); // 将根节点入队
    
    while (!queue.isEmpty()) {
        int levelSize = queue.size(); // 当前层级的节点数量
        
        for (int i = 0; i < levelSize; i++) {
            TreeNode node = queue.poll(); // 出队当前节点
            System.out.print(node.val + " "); // 访问当前节点
            
            if (node.left != null) {
                queue.offer(node.left); // 左子节点入队
            }
            
            if (node.right != null) {
                queue.offer(node.right); // 右子节点入队
            }
        }
        
        System.out.println(); // 换行表示进入下一层级
    }
}

存储结构

顺序结构存储

使用数组来表示二叉树的结构。按照层级顺序依次将二叉树节点存储到数组中,空缺位置用特定值(如null)表示。这种存储结构适用于完全二叉树,因为不是完全二叉树会有空间的浪费,可以通过数组下标计算节点之间的关系。

特点

  • 顺序二叉树通常只考虑完全二叉树

  • 第n个元素的左子节点为 2* n +1

  • 第n个元素的右子节点为 2* n + 2

  • 第n个元素的

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇LeetCode98:验证二叉搜索树,居.. 下一篇一个全面、完整、稳定的 k8s 集群..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目