数据结构与算法分析:树与哈希表(一)

遇到的问题,都有解决方案,希望我的博客能为你提供一点帮助。

一、概述

背景:链表处理大量数据时,线性访问耗时多。二叉查找树多数操作平均运行时间为 O (log N),相对于链表树更加高效。

1.预备知识

1.1. 树的定义与基本概念

  • 树(Tree)​: 非线性数据结构,由节点(Node)和边(Edge)组成,满足以下条件:

    • 存在唯一根节点(Root),无父节点。
    • 除根节点外,每个节点有且仅有一个父节点。
    • 从根到任意节点有唯一路径,无环路。
  • 关键术语

    • 根节点(Root):树的顶端节点,没有父节点。

    • 子节点(Child):一个节点的直接下级节点。

    • 父节点(Parent):一个节点的直接上级节点。

    • 叶子节点(Leaf):没有子节点的节点。

    • 内部节点(Internal Node):至少有一个子节点的节点。

    • 子树(Subtree):一个节点及其所有后代节点构成的树。

    • 边(Edge):连接两个节点的线段。

    • 路径(Path):从某一节点到其子孙节点的连续边序列。

    • 深度(Depth):根节点到该节点的路径长度(根节点深度为0)。

    • 高度(Height):节点到最深叶子节点的路径长度(叶子节点高度为0)。

    • 树的深度=树的高度

    • 节点所在的层(level):从顶至底递增,根节点所在层为 1 。

    • 节点的度(degree):节点的子节点的数量。在二叉树中,度的取值范围是 0、1、2 。

python 复制代码
class TreeNode:
    def __init__(self, val, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def plot_tree(root):
    """可视化二叉树"""
    import matplotlib.pyplot as plt
    from matplotlib.patches import Circle
    
    fig, ax = plt.subplots(figsize=(10, 8))
    ax.set_aspect('equal')
    ax.axis('off')
    
    def get_height(node):
        if not node:
            return 0
        return 1 + max(get_height(node.left), get_height(node.right))
    
    tree_height = get_height(root)
    
    def plot_node(node, x, y, dx):
        if not node:
            return
        
        # 绘制当前节点
        circle = Circle((x, y), 0.3, fill=True, color='lightblue')
        ax.add_patch(circle)
        ax.text(x, y, str(node.val), ha='center', va='center', fontsize=12)
        
        # 绘制左子树
        if node.left:
            new_x = x - dx
            new_y = y - 1
            ax.plot([x, new_x], [y-0.3, new_y+0.3], 'k-', lw=1.5)
            plot_node(node.left, new_x, new_y, dx/2)
        
        # 绘制右子树
        if node.right:
            new_x = x + dx
            new_y = y - 1
            ax.plot([x, new_x], [y-0.3, new_y+0.3], 'k-', lw=1.5)
            plot_node(node.right, new_x, new_y, dx/2)
    
    plot_node(root, 0, tree_height-1, 2**(tree_height-2))
    plt.xlim(-2**(tree_height-1), 2**(tree_height-1))
    plt.ylim(-1, tree_height)
    plt.show()

# 测试用例
if __name__ == "__main__":
    # 构建一个示例树
    #       1
    #      / \
    #     2   3
    #    / \
    #   4   5
    root = TreeNode(1)
    root.left = TreeNode(2)
    root.right = TreeNode(3)
    root.left.left = TreeNode(4)
    root.left.right = TreeNode(5)
    
    plot_tree(root)

1.2树的递归定义

递归定义 是一种通过自我引用 来描述数据结构或算法的方式。对于树这种分层结构 ,递归定义尤其自然,因为每个子树本身也是一棵树。递归定义包含两个关键部分:

  1. 基线条件(Base Case)​:定义最简单、不可再分的情况(通常是空树或叶子节点)。
  2. 递归条件(Recursive Case)​ :通过组合更小的树来定义更大的树。

通用树的递归定义

一个树可以是:

  • 空树 (基线条件),或者一个根节点 ,连接若干个子树(递归条件),每个子树本身也是树。
数学表达

T=∅或T=(v,{T1​,T2​,...,Tn​})

  • v:根节点的值
  • {T1,T2,...,Tn}:子树集合

动态演示建树过程:

python 复制代码
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
import time

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

def build_tree_recursively(values, index=0):
    """
    递归构建二叉树
    :param values: 节点值列表
    :param index: 当前节点索引
    :return: 构建好的树节点
    """
    if index >= len(values) or values[index] is None:
        return None
    
    node = TreeNode(values[index])
    
    # 递归构建左子树
    node.left = build_tree_recursively(values, 2*index+1)
    
    # 递归构建右子树
    node.right = build_tree_recursively(values, 2*index+2)
    
    return node

def visualize_recursive_build(root, values):
    """
    可视化递归构建过程
    :param root: 树的根节点
    :param values: 节点值列表
    """
    fig, ax = plt.subplots(figsize=(12, 8))
    ax.set_aspect('equal')
    ax.axis('off')
    
    # 计算树的高度
    def get_height(node):
        if not node:
            return 0
        return 1 + max(get_height(node.left), get_height(node.right))
    
    tree_height = get_height(root)
    
    # 存储节点高度信息
    node_heights = {}
    
    def calc_heights(node):
        if not node:
            return 0
        h = 1 + max(calc_heights(node.left), calc_heights(node.right))
        node_heights[id(node)] = h - 1
        return h
    
    calc_heights(root)
    
    # 递归构建并可视化
    def recursive_build_visualize(node, x, y, dx, depth=0, is_new=False):
        if not node:
            return
        
        # 绘制当前节点
        color = 'red' if is_new else 'lightblue'
        circle = Circle((x, y), 0.35, fill=True, color=color, alpha=0.8)
        ax.add_patch(circle)
        
        # 显示节点信息
        node_info = f"值: {node.val}\n深度: {depth}\n高度: {node_heights.get(id(node), 0)}"
        ax.text(x, y, node_info, 
                ha='center', va='center', 
                fontsize=10, bbox=dict(facecolor='white', alpha=0.7))
        
        plt.pause(0.5)  # 暂停0.5秒展示当前步骤
        
        # 递归构建左子树
        if 2*values.index(node.val)+1 < len(values) and values[2*values.index(node.val)+1] is not None:
            new_x = x - dx
            new_y = y - 1.5
            ax.plot([x, new_x], [y-0.35, new_y+0.35], 'b-', lw=1.5, alpha=0.6)
            plt.pause(0.3)  # 展示连接线
            
            left_val = values[2*values.index(node.val)+1]
            left_node = TreeNode(left_val)
            node.left = left_node
            recursive_build_visualize(left_node, new_x, new_y, dx/2, depth+1, True)
        
        # 递归构建右子树
        if 2*values.index(node.val)+2 < len(values) and values[2*values.index(node.val)+2] is not None:
            new_x = x + dx
            new_y = y - 1.5
            ax.plot([x, new_x], [y-0.35, new_y+0.35], 'r-', lw=1.5, alpha=0.6)
            plt.pause(0.3)  # 展示连接线
            
            right_val = values[2*values.index(node.val)+2]
            right_node = TreeNode(right_val)
            node.right = right_node
            recursive_build_visualize(right_node, new_x, new_y, dx/2, depth+1, True)
    
    # 开始可视化构建过程
    plt.title("递归构建二叉树过程 (红色:新添加节点)", pad=20)
    recursive_build_visualize(root, 0, tree_height-1, 2**(tree_height-2))
    
    plt.xlim(-2**(tree_height-1), 2**(tree_height-1))
    plt.ylim(-tree_height, tree_height)
    
    # 设置中文字体
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 使用黑体显示中文
    plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
    plt.show()

# 示例使用
if __name__ == "__main__":
    # 定义节点值列表 (None表示空节点)
    values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    
    # 构建完整的树结构
    root = build_tree_recursively(values)
    
    # 可视化递归构建过程
    visualize_recursive_build(root, values)

演示视频可以在我的视频资源里看:20250330_101822-CSDN直播

2、二叉树(Binary Tree)

2.1. 定义

  • 每个节点最多有两个子节点(左子节点和右子节点)。

  • 结构示例

    python 复制代码
    class TreeNode:
        def __init__(self, val=0, left=None, right=None):
            self.val = val
            self.left = left
            self.right = right
二叉树的递归定义

一个二叉树可以是:

  • 空树 (基线条件),或者一个根节点 ,连接一个左子树 和一个右子树(递归条件),每个子树本身也是二叉树。
数学表达

2.2. 特殊二叉树类型

(1) 满二叉树(Full Binary Tree)
  • 每个节点要么是叶子节点,要么恰好有两个子节点

  • 示例

    python 复制代码
           1
        /     \
       2       3
      / \     / \
     4   5   6   7
(2) 完全二叉树(Complete Binary Tree)
  • 除最后一层外,其他层节点全满,且最后一层节点尽量靠左排列

  • 示例

    python 复制代码
          1
        /   \
       2     3
      / \   /
     4   5 6
  • 左子树所有节点值 < 根节点值 < 右子树所有节点值。

  • 作用:支持高效查找、插入、删除(时间复杂度 O(log n))。

  • 示例

    python 复制代码
          4
        /   \
       2     6
      / \   / \
     1   3 5   7

    2.3树的遍历法

python 复制代码
       1
    /     \
   2       3
  / \     / \
 4   5   6   7
2.3.1. 深度优先遍历(DFS)
  • 前序遍历(Preorder) :根 → 左 → 右
    示例1 → 2 → 4 → 5 → 3 → 6 → 7

    python 复制代码
    def preorder(root):
        if not root: return []
        return [root.val] + preorder(root.left) + preorder(root.right)
  • 中序遍历(Inorder) :左 → 根 → 右
    BST 中序遍历结果有序
    示例4 → 2 → 5 → 1 → 6 → 3 → 7

    python 复制代码
    def inorder(root):
        if not root: return []
        return inorder(root.left) + [root.val] + inorder(root.right)
  • 后序遍历(Postorder) :左 → 右 → 根
    示例4 → 5 → 2 → 6 → 7 → 3 → 1

    python 复制代码
    def postorder(root):
        if not root: return []
        return postorder(root.left) + postorder(root.right) + [root.val]
2.3.2. 广度优先遍历(BFS / 层序遍历)
  • 按层次逐层访问节点。

  • 示例1 → 2 → 3 → 4 → 5 → 6 → 7

    python 复制代码
    from collections import deque
    def level_order(root):
        if not root: return []
        queue = deque([root])
        res = []
        while queue:
            node = queue.popleft()
            res.append(node.val)
            if node.left: queue.append(node.left)
            if node.right: queue.append(node.right)
        return res

    完整代码示例:

python 复制代码
class TreeNode:
    """
    二叉树节点类
    
    属性:
        val: 节点值
        left: 左子节点
        right: 右子节点
    """
    def __init__(self, val=0, left=None, right=None):
        """
        初始化二叉树节点
        
        参数:
            val: 节点值,默认为0
            left: 左子节点,默认为None
            right: 右子节点,默认为None
        """
        self.val = val
        self.left = left
        self.right = right

def preorder(root):
    """
    前序遍历二叉树
    
    参数:
        root: 二叉树根节点
        
    返回:
        包含前序遍历结果的列表
    """
    if not root: return []
    return [root.val] + preorder(root.left) + preorder(root.right)

def inorder(root):
    """
    中序遍历二叉树
    
    参数:
        root: 二叉树根节点
        
    返回:
        包含中序遍历结果的列表
    """
    if not root: return []
    return inorder(root.left) + [root.val] + inorder(root.right)

def postorder(root):
    """
    后序遍历二叉树
    
    参数:
        root: 二叉树根节点
        
    返回:
        包含后序遍历结果的列表
    """
    if not root: return []
    return postorder(root.left) + postorder(root.right) + [root.val]

from collections import deque
def level_order(root):
    """
    层序遍历二叉树
    
    参数:
        root: 二叉树根节点
        
    返回:
        包含层序遍历结果的列表
    """
    if not root: return []
    queue = deque([root])
    res = []
    while queue:
        node = queue.popleft()
        res.append(node.val)
        if node.left: queue.append(node.left)
        if node.right: queue.append(node.right)
    return res

# 示例用法
if __name__ == "__main__":
    # 构建示例树
    #       1
    #      / \
    #     2   3
    #    / \ / \
    #   4  5 6 7
    root = TreeNode(1)
    root.left = TreeNode(2)
    root.right = TreeNode(3)
    root.left.left = TreeNode(4)
    root.left.right = TreeNode(5)
    root.right.left = TreeNode(6)
    root.right.right = TreeNode(7)

    print("前序遍历:", preorder(root))
    print("中序遍历:", inorder(root))
    print("后序遍历:", postorder(root))
    print("层序遍历:", level_order(root))

C++简易版

cpp 复制代码
#include <iostream>
#include <vector>
#include <queue>

using namespace std;

// 二叉树节点结构体
struct TreeNode {
    int val;         // 节点存储的值
    TreeNode* left;  // 指向左子节点的指针
    TreeNode* right; // 指向右子节点的指针
    // 构造函数
    // 参数x: 节点存储的整数值
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

// 前序遍历二叉树(根-左-右)
// 参数root: 二叉树的根节点
// 返回值: 包含前序遍历结果的整数向量
vector<int> preorder(TreeNode* root) {
    if (!root) return {}; // 空树返回空向量
    vector<int> result;
    result.push_back(root->val); // 访问根节点
    vector<int> left = preorder(root->left); // 递归遍历左子树
    vector<int> right = preorder(root->right); // 递归遍历右子树
    result.insert(result.end(), left.begin(), left.end()); // 合并左子树结果
    result.insert(result.end(), right.begin(), right.end()); // 合并右子树结果
    return result;
}

// 中序遍历二叉树(左-根-右)
// 参数root: 二叉树的根节点
// 返回值: 包含中序遍历结果的整数向量
vector<int> inorder(TreeNode* root) {
    if (!root) return {}; // 空树返回空向量
    vector<int> left = inorder(root->left); // 递归遍历左子树
    vector<int> result;
    result.push_back(root->val); // 访问根节点
    vector<int> right = inorder(root->right); // 递归遍历右子树
    left.insert(left.end(), result.begin(), result.end()); // 合并根节点结果
    left.insert(left.end(), right.begin(), right.end()); // 合并右子树结果
    return left;
}

// 后序遍历二叉树(左-右-根)
// 参数root: 二叉树的根节点
// 返回值: 包含后序遍历结果的整数向量
vector<int> postorder(TreeNode* root) {
    if (!root) return {}; // 空树返回空向量
    vector<int> left = postorder(root->left); // 递归遍历左子树
    vector<int> right = postorder(root->right); // 递归遍历右子树
    right.push_back(root->val); // 访问根节点
    left.insert(left.end(), right.begin(), right.end()); // 合并右子树和根节点结果
    return left;
}

// 层序遍历二叉树(广度优先)
// 参数root: 二叉树的根节点
// 返回值: 包含层序遍历结果的整数向量
vector<int> levelOrder(TreeNode* root) {
    if (!root) return {}; // 空树返回空向量
    queue<TreeNode*> q; // 使用队列辅助遍历
    q.push(root); // 根节点入队
    vector<int> result;
    while (!q.empty()) {
        TreeNode* node = q.front(); // 取出队首节点
        q.pop();
        result.push_back(node->val); // 访问当前节点
        if (node->left) q.push(node->left); // 左子节点入队
        if (node->right) q.push(node->right); // 右子节点入队
    }
    return result;
}

int main() {
    // 构建示例树
    //       1
    //      / \
    //     2   3
    //    / \ / \
    //   4  5 6 7
    // 这是一个完全二叉树,用于测试各种遍历方法
    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);
    root->right->left = new TreeNode(6);
    root->right->right = new TreeNode(7);

    cout << "前序遍历: ";
    for (int num : preorder(root)) {
        cout << num << " ";
    }
    cout << endl;

    cout << "中序遍历: ";
    for (int num : inorder(root)) {
        cout << num << " ";
    }
    cout << endl;

    cout << "后序遍历: ";
    for (int num : postorder(root)) {
        cout << num << " ";
    }
    cout << endl;

    cout << "层序遍历: ";
    for (int num : levelOrder(root)) {
        cout << num << " ";
    }
    cout << endl;

    // 释放内存
    delete root->right->right;
    delete root->right->left;
    delete root->left->right;
    delete root->left->left;
    delete root->right;
    delete root->left;
    delete root;

    return 0;
}

3.二叉树的数组表示

核心思想 :用连续的内存空间(数组)存储二叉树节点,通过索引计算确定节点间的父子关系。

适用场景
  • 完全二叉树:数组表示最紧凑,无空间浪费。

  • 非完全二叉树:可能存在空间浪费,需用特殊值标记空节点。

3.1、数组存储规则

3.1.1. 索引分配规则(适用于完美二叉树)

假设数组从 索引0 开始存储:

  • 根节点 :索引为 0

  • 父节点索引 i

    • 左子节点索引2*i + 1

    • 右子节点索引2*i + 2

  • 子节点索引 j

    • 父节点索引⌊(j-1)/2⌋(向下取整)
2. 空节点标记(非完美二叉树)
  • 用特定值(如 Nonenull 或特殊符号)表示缺失的节点。

3.1.2、示例分析
示例1:完全二叉树的数组表示
  • 树结构

    复制代码
           1
        /     \
       2       3
      / \     / \
     4   5   6   7
  • 数组表示

    复制代码
    [1, 2, 3, 4, 5, 6, 7]
    • 索引关系

      • 根节点 1 的索引为 0

      • 左子节点 2 的索引为 12*0+1)。

      • 右子节点 3 的索引为 22*0+2)。

      • 节点 4(索引 3)的父节点为 1⌊(3-1)/2⌋=1)。

示例2:非完全二叉树的数组表示
  • 树结构

    复制代码
          1
        /   \
       2     3
        \     \
         5     7
  • 数组表示 (用 null 填充空缺):

    复制代码
    [1, 2, 3, null, 5, null, 7]
    • 说明

      • 索引 3(左子节点位置)为 null,表示节点 2 无左子节点。

      • 索引 5(右子节点位置)为 null,表示节点 3 无左子节点。


3.2、数组表示 vs. 链式表示

维度 数组表示 链式表示
空间效率 完全二叉树高效;非完全二叉树可能浪费空间 灵活,无空间浪费
访问速度 直接通过索引计算,速度快 需遍历指针,速度较慢
插入/删除 需要移动元素,效率低 修改指针即可,效率高
适用场景 完全二叉树、堆 任意二叉树(尤其是非完全树)

3.3、代码实现

3.3.1. 根据数组构建二叉树(链式结构)
cpp 复制代码
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def build_tree(arr, i=0):
    if i >= len(arr) or arr[i] is None:
        return None
    root = TreeNode(arr[i])
    root.left = build_tree(arr, 2*i + 1)
    root.right = build_tree(arr, 2*i + 2)
    return root

# 示例:构建示例2的非完全二叉树
arr = [1, 2, 3, None, 5, None, 7]
root = build_tree(arr)

C++版

cpp 复制代码
#include <vector>
#include <queue>
#include <iostream>
using namespace std;

/**
 * @brief 二叉树节点结构
 * @param val 存储的数据元素
 * @param left 指向左子节点的指针
 * @param right 指向右子节点的指针
 *  */
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x = 0, TreeNode* l = nullptr, TreeNode* r = nullptr) : val(x), left(l), right(r) {}
};

/**
 * @brief 根据数组构建二叉树
 * @param arr 包含二叉树节点值的数组,-1表示空节点
 * @param i 当前处理的数组索引,默认为0(根节点)
 * @return TreeNode* 构建完成的二叉树根节点
 * @note 使用完毕后需要调用deleteTree释放内存
 */
TreeNode* buildTree(const vector<int>& arr, int i = 0) {
    // 参数校验
    if (arr.empty()) {
        return nullptr;
    }
    
    // 递归终止条件:索引越界或遇到空节点标记
    if (i < 0 || i >= arr.size() || arr[i] == -1) {
        return nullptr;
    }
    
    // 创建当前节点并递归构建左右子树
    TreeNode* root = new TreeNode(arr[i]);
    root->left = buildTree(arr, 2 * i + 1);
    root->right = buildTree(arr, 2 * i + 2);
    return root;
}

/**
 * @brief 释放二叉树内存
 * @param root 二叉树根节点
 */
void deleteTree(TreeNode* root) {
    if (!root) return;
    deleteTree(root->left);
    deleteTree(root->right);
    delete root;
}

void printTree(TreeNode* root) {
    if (!root) {
        return;  // 空节点,直接返回  
    }
    queue<TreeNode*> q;  // 队列用于层次遍历    
    q.push(root);  // 根节点入队

    while (!q.empty()) {
        TreeNode* curr = q.front();
        q.pop();
        cout << curr->val << " ";  // 输出当前节点的值

        if (curr->left) {
            q.push(curr->left);  // 左子节点入队
      
        } else {}                 // 空节点,不做处理

        if (curr->right) {
            q.push(curr->right);  // 右子节点入队
        } else {}                 // 空节点,不做处理
    }   
}

/**
 * @brief 演示二叉树构建和删除
 */
int main() {
    // 示例数组表示二叉树
    vector<int> treeData = {1, 2, 3, -1, 4, 5, 6, -1, -1, 7, 8};
    
    // 构建二叉树
    TreeNode* root = buildTree(treeData);
    
    // 这里可以添加遍历或其他操作
    cout << "Tree in level order: ";
    printTree(root);
    cout << endl << "Tree deleted." << endl;
    // 释放内存
    deleteTree(root);
    
    return 0;
3.3.2. 将二叉树转为数组表示
cpp 复制代码
def tree_to_array(root):
    if not root:
        return []
    queue = [root]
    res = []
    while queue:
        node = queue.pop(0)
        if node:
            res.append(node.val)
            queue.append(node.left)
            queue.append(node.right)
        else:
            res.append(None)
    # 去除末尾的 None(可选)
    while res and res[-1] is None:
        res.pop()
    return res

# 示例:将链式树转回数组
print(tree_to_array(root))  # 输出 [1, 2, 3, None, 5, None, 7]

c++版

cpp 复制代码
#include <vector>
#include <queue>
#include <iostream>
#include <memory>
using namespace std;

/**
 * @brief 二叉树节点结构
 * 使用智能指针管理内存,防止内存泄漏
 */
struct TreeNode {
    int val;
    shared_ptr<TreeNode> left;
    shared_ptr<TreeNode> right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};


/**
 * @brief 将二叉树转换为数组表示(层次遍历)
 * @param root 二叉树根节点
 * @return 包含节点值的vector,空节点用-1表示
 * @note 使用智能指针避免内存泄漏
 */
vector<int> treeToArray(shared_ptr<TreeNode> root) {
    vector<int> result;
    if (!root) {
        return result;
    }
    
    queue<shared_ptr<TreeNode>> q;
    q.push(root);
    
    while (!q.empty()) {
        auto node = q.front();
        q.pop();
        
        if (node) {
            result.push_back(node->val);
            q.push(node->left);
            q.push(node->right);
        } else {
            result.push_back(-1); // 使用-1表示空节点
        }
    }
    
    // 去除末尾的-1(可选)
    while (!result.empty() && result.back() == -1) {
        result.pop_back();
    }
    
    return result;
}


int main() {
    try {
        // 构建示例二叉树
        auto root = make_shared<TreeNode>(1);
        root->left = make_shared<TreeNode>(2);
        root->right = make_shared<TreeNode>(3);
        root->left->right = make_shared<TreeNode>(5);
        root->right->right = make_shared<TreeNode>(7);
        
        // 转换为数组并打印
        vector<int> arr = treeToArray(root);
        
        cout << "层次遍历结果: ";
        for (int val : arr) {
            cout << val << " ";
        }
        cout << endl;
        
        // 输出: 1 2 3 -1 5 -1 7 
    } catch (const exception& e) {
        cerr << "错误: " << e.what() << endl;
        return 1;
    }
    
    return 0;
}
相关推荐
人生在勤,不索何获-白大侠9 分钟前
day15——Java常用API(二):常见算法、正则表达式与异常处理详解
java·算法·正则表达式
小张成长计划..21 分钟前
双向链表的实现
数据结构·链表
s1533527 分钟前
数据结构之顺序表,链表,栈,队列
数据结构·数据库
Wo3Shi4七43 分钟前
双向队列
数据结构·算法·go
Wo3Shi4七1 小时前
列表
数据结构·算法·go
Wo3Shi4七1 小时前
链表
数据结构·算法·go
Wo3Shi4七1 小时前
数组
数据结构·算法·go
CoovallyAIHub1 小时前
YOLOv13都来了,目标检测还卷得动吗?别急,还有这些新方向!
深度学习·算法·计算机视觉
北方有星辰zz1 小时前
数据结构:栈
java·开发语言·数据结构
zl_dfq1 小时前
数据结构之 【树的简介】(树的(相关)概念、二叉树的概念、部分性质、满二叉树、完全二叉树)
数据结构