算法学习——中级篇 | 青训营笔记

109 阅读2分钟

【收集】在构思笔记层中写下即时想法或大纲,亦或是会议记录或你对学习资料的注解

这是我参与「第四届青训营」笔记创作活动的的第4天

⼀、数据结构的存储⽅式

数据结构的存储⽅式只有两种:数组(顺序存储)和链表(链式存储)。

这句话怎么理解,不是还有散列表、栈、队列、堆、树、图等等各种数据结

构吗?

我们分析问题,⼀定要有递归的思想,⾃顶向下,从抽象到具体。你上来就

列出这么多,那些都属于「上层建筑」,⽽数组和链表才是「结构基础」。

因为那些多样化的数据结构,究其源头,都是在链表或者数组上的特殊操

作,API 不同⽽已。

⽐如说「队列」、「栈」这两种数据结构既可以使⽤链表也可以使⽤数组实

现。⽤数组实现,就要处理扩容缩容的问题;⽤链表实现,没有这个问题,

但需要更多的内存空间存储节点指针。

⼆、数据结构的基本操作

对于任何数据结构,其基本操作⽆⾮遍历 + 访问,再具体⼀点就是:增删

查改。

数据结构种类很多,但它们存在的⽬的都是在不同的应⽤场景,尽可能⾼效

地增删查改。话说这不就是数据结构的使命么?

如何遍历 + 访问?我们仍然从最⾼层来看,各种数据结构的遍历 + 访问⽆

⾮两种形式:线性的和⾮线性的。

线性就是 for/while 迭代为代表,⾮线性就是递归为代表。再具体⼀步,⽆

⾮以下⼏种框架:

数组遍历框架,典型的线性迭代结构:

\

\

void traverse(int[] arr) {

for (int i = 0; i < arr.length; i++) {

// 迭代访问 arr[i]

}

}

链表遍历框架,兼具迭代和递归结构:

/* 基本的单链表节点 */

class ListNode {

int val;

ListNode next;

}

void traverse(ListNode head) {

for (ListNode p = head; p != null; p = p.next) {

// 迭代访问 p.val

}

}

void traverse(ListNode head) {

// 递归访问 head.val

traverse(head.next)

\


\