这是我参与更文挑战的第4天,活动详情查看: 更文挑战
前言
公众号给npy的前端秘籍
加vx👉16639199716,拉你进群嗷~❤️
数据结构中的链表还是很重要的,所以本次学习一下链表,做一下总结,分享给大家🤭
双向链表
尽管从链表的头结点遍历到尾节点很简单,但是反过来,从后向前遍历则没有那么简单,通过给Node对象增加一个属性,该属性存储指向前驱节点的链接,这样就容易多了,此时向链表插入一个节点需要更多的工作,我们需要指出该节点正确的前驱和后继。但是从链表删除节点时,效率提高了,不需要查找待删除节点的前驱节点了。
class Node {
constructor (element) {
this.element = element
this.prev = null
this.next = null
}
}
双向链表的insert方法和单向链表的类似,但是需要设置新节点的prev属性,使其指向该节点的前驱。
function insert(newElement,item) {
var newNode = new Node(newElement)
var current = this.find(item)
newNode.next = current.next
newNode.prev = cuurrent
current.next = newNode
}
删除也是一样,代码就不写了,网上很多都可以代码,可以看看人家怎么写的🤭
题目描述
将两个升序链表合并为一个新的 「升序」 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
解法一:双指针法
var mergeTwoLists = function (l1, l2) {
const res = new ListNode(0);
let p = res;// 需要指向新链表的最后一个节点
let p1 = l1;
let p2 = l2;
while (p1 && p2) {
if (p1.val < p2.val) {
p.next = p1;
p1 = p1.next
} else {
p.next = p2;
p2 = p2.next
}
p = p.next;
}
if (p1) {
p.next = p1;
}
if(p2){
p.next=p2;
}
return res.next;
};
//时间复杂度O(n)
//空间复杂度O(1)
解法二:递归
编程技巧:递归 + 原地斩链相连
-
递归比较查看两个链表哪个元素先小 就斩断此元素位置链条⛓️连接到另一链表上 如此也不需要另外开辟存储空间
-
斩断后 重连铁链的动作因为要自动非人工 所以需要程序自己调用自己 即为递归
-
斩断后需要连的结点 通过 return 最小结点 即动态更新 斩断结点位置
-
随时连接下一个符合要求的位置(x.next = 求下一个需要连接的结点位置(即程序自动搜索即递归) && x = 下一个需要连接的结点位置)
-
返回修改后的 l1头结点的链表 或 l2头结点的链表
var mergeTwoLists = function(l1, l2) {
if(l1 == null){
return l2;
}
if(l2 == null){
return l1;
}
if(l1.val <= l2.val){
l1.next = mergeTwoLists(l1.next,l2);
return l1;
}else{
l2.next = mergeTwoLists(l1,l2.next);
return l2;
}
}
// 时间复杂度O(n)
// 空间复杂度O(n)
总结
刷题打卡第10天,选择力扣第21题,学习了链表的相关知识,一起加油哇~
❤️ 感谢大家
如果你觉得这篇内容对你挺有有帮助的话: 点赞支持下吧,让更多的人也能看到这篇内容(收藏不点赞,都是耍流氓 -_-)关注公众号给npy的前端秘籍,我们一起学习一起进步。 觉得不错的话,也可以阅读其他文章(感谢朋友的鼓励与支持🌹🌹🌹)