首页 > 其他分享 >数据结构之树(遍历)

数据结构之树(遍历)

时间:2023-11-05 17:35:38浏览次数:27  
标签:node 遍历 TreeNode 之树 right 数据结构 root 节点

二叉树遍历的规则

1. 根据根节点(父节点)的位置在最前面、在左子节点、右子节点中间、最后面,分为前序、中序、后序。

2. 除了根(父节点)特殊以外,都是先左节点、后右节点。

前序遍历

 

1. 一个子树一个子树的看

2. 前序:根(父)--> 左子节点--->子树  .....    -->右子节点

 

第1个子树:ABC组成,前序是ABC

因为B又是一个树(节点数大于1,右BDE组成),因此子树前序是BDE,替换后是ABDEC

因为C又是一个数,其前序:CF,替换后ABDECF

因此此树前序遍历为:ABDECF

中序遍历

与前序遍历的逻辑是一样的。

1. 第1个子树(包含根节点的)的中序遍历是:BAC

2. 因为B又是一个子树(由BDE节点组成)其中序遍历是:DBE,替换第1步骤的结果BAC的中即为DBEAC

3.因为C又是一个子树(由CF节点组成),其中序遍历是CF(没有左节点就直接根节点),替换步骤1中的C,最终中序遍历:DBEACF

 

后序遍历

与前序、中序的遍历逻辑一样

第1步: 根节点组成的树:ABC,其后序遍历:BCA

第2步:B又是一个树(BDE组成),其后序遍历:DEB,替换第1步骤的结果中的B:DEBCA

第3步:因C也是一个树(CF组成),其后序遍历: FC,替换步骤1的C,结果为DEBFCA

Java前中后序遍历示例

 

1. 树节点

定义一个类表示树节点,记录当前节点存储的数据以及其左右节点。

public class TreeNode {
    // 数据
    int data;
    // 左子节点
    TreeNode left;
    // 右子节点
    TreeNode right;
    public TreeNode(int data) {
        this.data = data;
        this.left = null;
        this.right = null;
    }
}

 

2. 树对象

定义一个类表示树本身,要记录根节点以及新增节点。

import java.util.LinkedList;
import java.util.Queue;

/**
 * 树类即一个BinaryTree对象代表一个树
 */
public class BinaryTree {

    TreeNode root;

    public BinaryTree(int data) {
        this.root = new TreeNode(data);
    }

    public void insert(int data) {
        TreeNode newNode = new TreeNode(data);
        if (root == null) {
            root = newNode;
            return;
        }
        // 每次都需要遍历,塑造树
        // 0. 创建一个容器,记录需要处理左右子节点的树节点
        Queue<TreeNode> queue = new LinkedList<>();
        // 1. 根入链
        queue.offer(root);
        // 2. 遍历 : 塑造树
        while (!queue.isEmpty()) {
            // 2.1 遍历所有节点,判断左右子节点是否为空,顺序先左后右
            TreeNode current = queue.poll();
            // 2.2 左子节点为空,当前插入节点作为其左节点
            if (current.left == null) {
                current.left = newNode;
                return;
            } else {
                // 2.2 左子节点不为空,入链塑造树(在以后的循环为其塑造左右节点)
                queue.offer(current.left);
            }
            // 2.3 遍历所有节点,判断右子节点是否为空
            //  为空,当前插入节点作为其右子节点
            if (current.right == null) {
                current.right = newNode;
                return;
            } else {
                // 不为空,入链,塑造树(在以后的循环为其塑造左右节点)
                queue.offer(current.right);
            }
        }
    }
}

测试类

public class Main {
    public static void main(String[] args) {
        BinaryTree binaryTree = new BinaryTree(1);
        binaryTree.insert(2);
        binaryTree.insert(3);
        binaryTree.insert(4);
        binaryTree.insert(5);
        System.out.println("Binary Tree traversal:");
        traversalBinaryTree(binaryTree.root);
        System.out.println();
        inorderTraversal(binaryTree.root);
        System.out.println();
        postorderTraversal(binaryTree.root);
    }

    // 前序遍历树
    public static void traversalBinaryTree(TreeNode root) {
        if (root != null) {
            System.out.print(root.data + " ");
            traversalBinaryTree(root.left);
            traversalBinaryTree(root.right);
        }
    }

    // 中序
    public static void inorderTraversal(TreeNode root) {
        if (root != null) {
            inorderTraversal(root.left);
            System.out.print(root.data + " ");
            inorderTraversal(root.right);
        }
    }

    // 后序
    public static void postorderTraversal(TreeNode root) {
        if (root != null) {
            postorderTraversal(root.left);
            postorderTraversal(root.right);
            System.out.print(root.data + " ");
        }
    }


}

输出结果:

Binary Tree traversal:
1 2 4 5 3 
4 2 5 1 3 
4 5 2 3 1 

 

Python前中后序遍历示例

 

class TreeNode:
    def __init__(self, value):
        self.value = value
        self.left = None
        self.right = None


class BinaryTree:

    def __init__(self, value):
        self.root = TreeNode(value)

    def insert(self, data):
        # 创建节点
        insertNode = TreeNode(data)
        if self.root is None:
            self.root = insertNode
        # 存储节点,用于遍历
        arr = [self.root]
        while len(arr) > 0:
            tmp = arr.pop(0)  # pop不指定索引,默认删除最后1个元素
            if tmp.left is None:
                tmp.left = insertNode
                return
            else:
                arr.append(tmp.left)
            if tmp.right is None:
                tmp.right = insertNode
                return
            else:
                arr.append(tmp.right)


'''
前序遍历
'''


def preorder_traversal(node):
    if node:
        print(node.value, end=" ")
        preorder_traversal(node.left)
        preorder_traversal(node.right)


'''
中序遍历
'''


def inorder_traversal(node):
    if node:
        inorder_traversal(node.left)
        print(node.value, end=" ")
        inorder_traversal(node.right)


'''
后序遍历
'''


def postorder_traversal(node):
    if node:
        postorder_traversal(node.left)
        postorder_traversal(node.right)
        print(node.value, end=" ")


tree = BinaryTree(1)
tree.insert(2)
tree.insert(3)
tree.insert(4)
tree.insert(5)
preorder_traversal(tree.root)
print()
inorder_traversal(tree.root)
print()
postorder_traversal(tree.root)

  

输出:

1 2 4 5 3 
4 2 5 1 3 
4 5 2 3 1 

  

 

标签:node,遍历,TreeNode,之树,right,数据结构,root,节点
From: https://www.cnblogs.com/allenxx/p/17810780.html

相关文章

  • 102. 二叉树的层序遍历(中)
    目录题目法一、BFS法二、DFS题目给你二叉树的根节点root,返回其节点值的层序遍历。(即逐层地,从左到右访问所有节点)。示例1:输入:root=[3,9,20,null,null,15,7]输出:[[3],[9,20],[15,7]]示例2:输入:root=[1]输出:[[1]]示例3:输入:root=[]输出:[]法一、BFS......
  • Redis 有哪些数据结构?
    Redis有五种基本数据结构。string字符串最基础的数据结构。字符串类型的值实际可以是字符串(简单的字符串、复杂的字符串(例如JSON、XML))、数字(整数、浮点数),甚至是二进制(图片、音频、视频),但是值最大不能超过512MB。字符串主要有以下几个典型使用场景:缓存功能计数共享Session......
  • 数据结构之树(二叉树的存储方式之链表)
    JavaJava中可以使用链表来实现二叉树的存储。1.链表实现二叉树的原理:   链表是由节点组成的数据结构,每个节点包含一个数据和指向下一个节点的指针。  在链表中,可以将二叉树的每个节点都看作一个链表节点,同时维护一个指向左子节点的指针和一个指向右子节点的指针。通过......
  • Java小白学习记录--------常见的一维数组遍历方法
    一维数组:for循环遍历:int[]myArray={1,2,3,4,5};for(inti=0;i<myArray.length;i++){System.out.println("myArray["+i+"]="+myArray[i]);//输出数组中的每个元素} for-each循环遍历数组(增强for循环遍历)int[]myArray={1,2,3,4,5};......
  • 队列(Queue):先进先出(FIFO)的数据结构
    队列是一种基本的数据结构,用于在计算机科学和编程中管理数据的存储和访问。队列遵循先进先出(FirstIn,FirstOut,FIFO)原则,即最早入队的元素首先出队。这种数据结构模拟了物理世界中的队列,如排队等待服务的人。在本篇博客中,我们将详细介绍队列的概念、用途、实现以及如何在编程中......
  • 数据结构:详解顺序串
    《详解循环队栈》目录:顺序串的定义及其特点顺序串的实现完整Demo运行截图小结参考文献 顺序串的定义及其特点顺序串的存储结构的和线性表一样,也是主要分为顺序存储结构和链式存储结构两类,前者简称顺序串,顺序串和顺序表一样,只不过它的每个元素仅由一个字符组成,在......
  • 一、数据结构入门
    “程序(Program)=数据结构(DataStructure)+算法(Algorithm)”数学基础1. 指数指数是幂运算aⁿ(a≠0)中的一个参数,a为底数,n为指数,指数位于底数的右上角,幂运算表示指数个底数相乘。如43=4*4*4一些基本的公式2. 对数在数学中,对数是对求幂的逆运算,正如除法是乘法的倒数,反之亦然。因此,对......
  • 数据结构记录-链表
    1、单链表1、单链表的组成最基本的单链表组成如下:typedefstructLink{charelem;/*数据域*/structLink*next;/*指针域*/}link;/*节点名,每个阶段都是一个Link结构体*/为什么这样的就是链表呢,需要从这个结构体内部组成来看,structLinknext;定义了一个指针变......
  • 前端学习笔记202310学习笔记第一百零玖天-vue3-链式调用&对象属性与遍历&this指向&cal
    ......
  • 前端学习笔记202310学习笔记第一百零玖天-vue3-链式调用&对象属性与遍历&this指向&cal
    functiontest1(){console.log(arguments.callee)functiontest2(){console.log(arguments.callee)}test2()}test1()functionsum(n){if(n<=1){return1}returnn+sum(n-1)}varres=sum(10)console.log(res)运......