初级程序员必备的十大技能之基础数据结构与算法(一)

简介: 教程来源 https://tmywi.cn/ 数据结构与算法是程序员的“内功”:决定代码性能、面试成败与问题解决能力。本文从时间/空间复杂度讲起,详解7大结构与5大算法思想,配原理、代码与执行分析,助你夯实编程根基。

为什么数据结构与算法是程序员的“内功”
数据结构与算法是编程世界的基石。如果把编程比作建造房屋,那么:

编程语言是砖瓦水泥(工具)

数据结构是建筑结构(如何组织材料)

算法是施工方案(如何高效建造)

很多初级程序员会问:“我只是写业务逻辑,需要学算法吗?”

答案是:绝对需要。

理由很简单:

写出高性能代码:同样的功能,算法优劣决定程序是 0.1 秒完成还是 10 秒卡死

面试必考:大厂面试 80% 的时间都在考察数据结构与算法

解决问题的工具:遇到复杂问题,数据结构与算法是你最锋利的武器

代码质量的保障:理解底层原理才能写出健壮的代码

本文将从零开始,带你系统掌握初级程序员必须吃透的 7 大数据结构和 5 大算法思想,每一部分都有详细的原理讲解、代码实现和执行过程分析。

一、时间复杂度与空间复杂度:衡量算法的尺子

在学习具体的数据结构之前,我们必须先学会如何衡量一个算法的好坏。

1.1 什么是时间复杂度?
时间复杂度描述了算法执行时间随输入规模增长的变化趋势。它不关心具体运行时间(因为机器性能不同),而是关心操作次数的增长率。
https://fndvx.cn/
大O表示法:忽略常数项和低阶项,只保留最高阶项。
image.png
1.2 时间复杂度计算实战

// O(1) - 常数时间
// 无论输入多大,操作次数固定
function getFirstElement(arr) {
    return arr[0];  // 只做一次操作
}

function isEven(num) {
    return num % 2 === 0;  // 一次取余,一次比较
}
// O(n) - 线性时间
// 操作次数与输入规模成正比
function findMax(arr) {
    let max = arr[0];
    for (let i = 1; i < arr.length; i++) {  // 循环 n-1 次
        if (arr[i] > max) {
            max = arr[i];
        }
    }
    return max;
}
// 总操作次数 ≈ n,所以是 O(n)
// O(n²) - 平方时间
// 常见于双重循环
function bubbleSort(arr) {
    const n = arr.length;
    for (let i = 0; i < n; i++) {           // 外层循环 n 次
        for (let j = 0; j < n - 1; j++) {   // 内层循环 n 次
            if (arr[j] > arr[j + 1]) {
                [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
            }
        }
    }
    return arr;
}
// 总操作次数 ≈ n × n = n²,所以是 O(n²)
// O(log n) - 对数时间
// 典型场景:二分查找
function binarySearch(arr, target) {
    let left = 0;
    let right = arr.length - 1;

    while (left <= right) {
        const mid = Math.floor((left + right) / 2);

        if (arr[mid] === target) {
            return mid;
        } else if (arr[mid] < target) {
            left = mid + 1;   // 抛弃左半部分
        } else {
            right = mid - 1;  // 抛弃右半部分
        }
    }
    return -1;
}
// 每次循环将搜索范围减半,操作次数 = log₂(n)
// 当 n=1,000,000 时,log₂(1e6) ≈ 20 次
// O(n log n) - 线性对数时间
// 典型场景:高效排序算法(归并排序、快速排序)
function mergeSort(arr) {
    if (arr.length <= 1) return arr;

    const mid = Math.floor(arr.length / 2);
    const left = mergeSort(arr.slice(0, mid));
    const right = mergeSort(arr.slice(mid));

    return merge(left, right);
}

function merge(left, right) {
    const result = [];
    let i = 0, j = 0;

    while (i < left.length && j < right.length) {
        if (left[i] <= right[j]) {
            result.push(left[i++]);
        } else {
            result.push(right[j++]);
        }
    }

    return result.concat(left.slice(i)).concat(right.slice(j));
}
// 归并排序将数组不断二分(log n 层),每层需要合并 n 个元素
// 总复杂度:n × log n

1.3 常见复杂度对比
image.png
1.4 空间复杂度
空间复杂度描述算法额外消耗的存储空间随输入规模的变化趋势。

// O(1) - 常数空间
// 只使用固定数量的额外变量
function sum(arr) {
    let total = 0;        // 1 个变量
    for (let i = 0; i < arr.length; i++) {
        total += arr[i];   // 复用同一个变量
    }
    return total;
}
// 无论数组多大,只用了 total 和 i 两个变量
// O(n) - 线性空间
// 需要创建与输入规模成比例的额外空间
function duplicateArray(arr) {
    const copy = new Array(arr.length);  // 新数组长度 = n
    for (let i = 0; i < arr.length; i++) {
        copy[i] = arr[i];
    }
    return copy;
}
// 额外空间与输入数组大小成正比
// O(n²) - 平方空间
// 典型场景:创建二维矩阵
function createMatrix(n) {
    const matrix = [];
    for (let i = 0; i < n; i++) {
        matrix[i] = new Array(n);  // 每行有 n 个元素
        for (let j = 0; j < n; j++) {
            matrix[i][j] = 0;
        }
    }
    return matrix;
}
// 总元素个数 = n × n = n²

1.5 复杂度分析技巧

// 技巧1:只看循环嵌套最深的部分
function example1(arr) {
    let sum = 0;                    // O(1)
    for (let i = 0; i < arr.length; i++) {  // O(n)
        sum += arr[i];
    }
    for (let i = 0; i < arr.length; i++) {  // O(n)
        for (let j = 0; j < arr.length; j++) {  // O(n²)
            console.log(i, j);
        }
    }
}
// 总体复杂度 = O(1) + O(n) + O(n²) = O(n²)(取最高阶)

// 技巧2:循环变量以乘法/除法增长的是对数级
function example2(n) {
    let i = 1;
    while (i < n) {
        i = i * 2;  // i 按倍数增长
    }
}
// 复杂度 = O(log n)

// 技巧3:递归算法可以用递归树分析
function fibonacci(n) {
    if (n <= 1) return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
}
// 复杂度 = O(2ⁿ)(指数爆炸)
相关文章
|
13天前
|
人工智能 JSON 供应链
畅用7个月无影 JVS Claw |手把手教你把JVS改造成「科研与产业地理情报可视化大师」
LucianaiB分享零成本畅用JVS Claw教程(学生认证享7个月使用权),并开源GeoMind项目——将JVS改造为科研与产业地理情报可视化AI助手,支持飞书文档解析、地理编码与腾讯地图可视化,助力产业关系图谱构建。
23495 11
畅用7个月无影 JVS Claw |手把手教你把JVS改造成「科研与产业地理情报可视化大师」
|
17天前
|
人工智能 缓存 BI
Claude Code + DeepSeek V4-Pro 真实评测:除了贵,没别的毛病
JeecgBoot AI专题研究 把 Claude Code 接入 DeepSeek V4Pro,跑完 Skills —— OA 审批、大屏、报表、部署 5 大实战场景后的真实体验 ![](https://oscimg.oschina.net/oscnet/up608d34aeb6bafc47f
5475 20
Claude Code + DeepSeek V4-Pro 真实评测:除了贵,没别的毛病
|
18天前
|
人工智能 JSON BI
DeepSeek V4 来了!超越 Claude Sonnet 4.5,赶紧对接 Claude Code 体验一把
JeecgBoot AI专题研究 把 Claude Code 接入 DeepSeek V4Pro 的真实体验与避坑记录 本文记录我将 Claude Code 对接 DeepSeek 最新模型(V4Pro)后的真实体验,测试了 Skills 自动化查询和积木报表 AI 建表两个场景——有惊喜,也踩
6539 16
|
7天前
|
人工智能 缓存 Shell
Claude Code 全攻略:命令大全 + 实战工作流(完整版)
Claude Code 是一款运行在终端环境下的 AI 编码助手,能够直接在项目目录中理解代码结构、编辑文件、执行命令、执行开发计划,并支持持久化记忆、上下文压缩、后台任务、多模型切换等专业能力。对于日常开发、项目维护、快速重构、代码审查等场景,它可以大幅减少手动操作、提升编码效率。本文从常用命令、界面模式、核心指令、记忆机制、图片处理、进阶工作流等维度完整说明,帮助开发者快速上手并稳定使用。
1664 3
|
6天前
|
前端开发 API 内存技术
对比claude code等编程cli工具与deepseek v4的适配情况
DeepSeek V4发布后,多家编程工具因未适配其强制要求的`reasoning_content`字段而报错。本文对比Claude Code、GitHub Copilot、Langcli、OpenCode及DeepSeek-TUI等主流工具的兼容性:Claude Code需按官方方式配置;Langcli表现最佳,开箱即用且无报错;Copilot与OpenCode暂未修复问题;DeepSeek-TUI尚处早期阶段。
1130 3
对比claude code等编程cli工具与deepseek v4的适配情况
|
2天前
|
人工智能 BI 持续交付
Claude Code 深度适配 DeepSeek V4-Pro 实测:全场景通关与真实体验报告
在 AI 编程工具日趋主流的今天,Claude Code 凭借强大的任务执行、工具调用与工程化能力,成为开发者与自动化运维的核心效率工具。但随着原生模型账号稳定性问题频发,寻找一套兼容、稳定、能力在线的替代方案变得尤为重要。DeepSeek V4-Pro 作为新一代高性能大模型,提供了完整兼容 Claude 协议的 API 接口,只需简单配置即可无缝驱动 Claude Code,且在任务执行、工具调用、复杂流程处理上表现极为稳定。
838 0
|
1月前
|
人工智能 自然语言处理 安全
Claude Code 全攻略:命令大全 + 实战工作流(建议收藏)
本文介绍了Claude Code终端AI助手的使用指南,主要内容包括:1)常用命令如版本查看、项目启动和更新;2)三种工作模式切换及界面说明;3)核心功能指令速查表,包含初始化、压缩对话、清除历史等操作;4)详细解析了/init、/help、/clear、/compact、/memory等关键命令的使用场景和语法。文章通过丰富的界面截图和场景示例,帮助开发者快速掌握如何通过命令行和交互界面高效使用Claude Code进行项目开发,特别强调了CLAUDE.md文件作为项目知识库的核心作用。
27256 65
Claude Code 全攻略:命令大全 + 实战工作流(建议收藏)