学习数据结构的框架思维

本文探讨了数据结构的基础——数组和链表,以及如何利用它们构建队列、栈、散列表、图和树等高级数据结构。文章强调了没有完美的数据结构,选择依赖于应用场景。同时阐述了数据结构的操作主要是增删改查,通过遍历和访问实现,提供了线性与非线性遍历的框架。最后,强调了算法和数据结构在解决问题中的协同作用,建议初学者从框架角度理解和学习。
摘要由CSDN通过智能技术生成

学习数据结构的框架思维

1. 数据结构千变万化,但万变不离宗

最高层的抽象,数据结构只有两种:数组和链表。
数组和链表才是「结构基础」,散列表、栈、队列等都可以看成是上层建筑,

依次来讲解‘上层建筑’怎么通过结构基础来实现

  • 比如说「队列」、「栈」这两种数据结构既可以使用链表也可以使用数组实现。用数组实现,就要处理扩容缩容的问题;用链表实现,没有这个问题,但需要更多的空间存储节点指针
  • 「图」的两种表示方法,邻接表就是链表邻接矩阵就是二维数组。邻接矩阵判断连通性迅速,并可以进行矩阵运算解决一些问题,但是一般比较耗费空间。邻接表比较节省空间,但是时间上肯定不如邻接矩阵快。
  • 「散列表」就是通过散列函数把键映射到一个大数组里。而且对于解决散列冲突的方法,拉链法需要链表特性,操作简单,但需要空间;线性探查法就需要数组特性,以便连续寻址,省空间,但操作稍微复杂些。
  • 「树」,用数组实现就是「堆」,因为「堆」是一个完全二叉树,用数组存储不需要节点指针,操作也比较简单;用链表实现就是很常见的那种「树」,因为不一定是完全二叉树,所以不适合用数组存储。为此,在这种链表「树」结构之上,又衍生出各种巧妙的设计,比如二叉搜索树、AVL 树、红黑树、区间树、B 树等等,以应对不同的问题。

总结:没有完美的数据结构

2、数据结构的操作:遍历 + 访问,具体一点:增删改查
遍历 + 访问:线性/非线性的
线性:for / while 为代表,非线性:递归为代表
数组遍历框架

void traverse(int[] arr) {
    for (int i = 0; i < arr.length; i++) {
        // 访问 arr[i]
    }
}```
**二叉树遍历框架,典型的非线性递归遍历结构:**

```java
void traverse(TreeNode root) {
    traverse(root.left)
    traverse(root.right)
}

上面只是最简单的形式,可以随意改造

链表遍历框架,兼具线性和非线性遍历结构:

void traverse(ListNode head) {
    for (ListNode p = head; p != null; p = p.next) {
        // 访问 p.val
    }
}

void traverse(ListNode head) {
    // 访问 head.val
    traverse(head.next)
}

二叉树框架又可以扩展为N叉树遍历框架:

void traverse(TreeNode root) {
    for (TreeNode child : root.children)
        traverse(child)
}

N 叉树的遍历又可以扩展为图的遍历,因为,图就是好几 N 叉棵树的结合体。你说图是可能出现环的?这个很好办,用个布尔数组 visited 做标记就行了

所谓框架,就是说不管具体问题是什么,这些代码都是永远无法脱离的结构,你可以把这个结构作为大纲,根据具体问题在框架上添加代码就行了。

3、为什么算法总是和数据结构同时出现
数据结构是工具,算法是通过合适的工具解决问题的方法。
初学算法的时候,一定要从第二点上面从框架上看问题,而不是纠结于细节问题,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值