数据结构与算法学习--第二次分享

今天我们数据结构与算法第三学习小组进行了第二次分享与讨论,主要围绕课程的第6、7、8小节进行讨论与分析。每个小组成员都进行了踊跃发言。
课程内容主要包括链表和栈,
实例:如何实现LRU(最近最少使用)缓存淘汰算法,以及实现浏览器前进后退功能
首先进行了理论阐述,主要包括链表的分类(单链表,双向链表,循环链表,循环双向链表),存储原理,插入或者删除数据,并进行了数据和链表的简单比较。
几个重要的概念,需要的同学可以去百度:
节点,头结点,尾节点,后继指针 next,前驱指针 prev

关于数组和链表的主要区别:
1.数组存储空间连续,链表存储不连续
2.时间复杂度:
数组:插入、删除的时间复杂度是O(n),随机访问的时间复杂度是O(1)。
链表:插入、删除的时间复杂度是O(1),随机访问的时间复杂端是O(n)。
相同点:
1.都是线性表

如何写出正确的链表代码:
技巧一:理解指针或引用的含义:
将某个变量赋值给指针,实际上就是将这个变量的地址赋值给指针,或者反过来说,指针中存储了这个变量的内存地址,指向了这个变量…通过指针就能找到这个变量。

技巧二:警惕指针丢失和内存泄漏
例如:一下的代码就发生了内存泄漏
p->next = x; // 将 p 的 next 指针指向 x 结点;
x->next = p->next; // 将 x 的结点的 next 指针指向 b 结点;
p->next 指针在完成第一步操作之后,已经不再指向结点b 了,而是指向结点 x。第 2 行代码相当于将 x 赋值给 x->next,自己指向自己。因此,整个链表也就断成了两半,从结点 b 往后的所有结点都无法访问到了。

技巧三:利用哨兵简化实现难度
针对链表的插入、删除操作,需要对插入第一个结点和删除最后一个结点的情况进行特殊处理。

极客时间版权所有: https://time.geekbang.org/column/article/41149

技巧四:重点留意边界条件处理
技巧五:举例画图,辅助思考
技巧六:多写多练,没有捷径

小节:
学习了以上内容,大家进行了扩展讨论,了解时空替换思想,即:“用时间换空间” 和 “空间换时间”,例如redis的使用。

思考:
1.如何实现LRU(最近最少使用)缓存淘汰算法
1)如果此数据之前已经被缓存在链表中了,我们遍历得到这个数据对应的结点,并将其从原来的位置删除,然后再插入到链表的头部。
2) 如果此数据没有在缓存链表中,又可以分为两种情况:如果此时缓存未满,则将此结点直接插入到链表的头部; 如果此时缓存已满,则链表尾结点删除,将新的数据结点插入链表的头部

2.回文字符串的判断:
1)快慢两个指针定位链表中点,同时逆序前半部分链表
2)已逆序的前半部分与后半部分进行比较
3)再次逆序前半部分链表
此方案的空间复杂度为O(1)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值