Python 链表笔记_python listnode是哪个库

一、Python所有方向的学习路线

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

二、学习软件

工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

三、入门学习视频

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

一直以来写leetcode题目时候,都是直接使用已经定义好的链表数据结构,那么问题是利用python如何构建自己的链表呢?如何进行相关链表操作呢?问题提出来之后,就来本文寻找答案。

链表结构定义

class ListNode:
	def \_\_init\_\_(self, x):
		self.val = x
		self.next = None
# 实例化 构建一个长度为1的链表
head = ListNode(0)

定义完了之后,在leetcode 中就用 指针指向头节点,
但是,看到输出链表都是以list 形式,例如长度为3的链表,输出[3, 2, 1], 也没有在 程序里指向,感到奇怪嘛?

构建链表

707. 设计链表是一个不错的例子,在python中设定链表类,例如 是单链表,随后设定如下操作:

  • 获取 index 的值
  • 在头部添加节点
  • 在索引处添加节点
  • 在尾部添加节点
  • 删除索引处节点

定义

class MyLinkedList:
    def \_\_init\_\_(self):
        self.size = 0 # 记录链表节点数
        self.head = ListNode(0) # 定义一个 伪头节点

这里使用伪头部节点,来使得当链表为空和不为空操作一样。这个时候对于链表的索引与长度记录有了困惑。
问:对于一个有头部伪节点的链表,它的索引范围是多少?
原链表 3->2->1->Null
索引 [0, 1, 2] 长度 3
有伪头节点链表 0->3->2->1->Null
索引 [0, 1, 2, 3] 长度 4

在索引处添加节点

    def addAtIndex(self, index: int, val: int) -> None:   
        if index > self.size: return # 超过索引,不添加; 如果等于长度,则在尾部添加
        if index < 0: index = 0 # 要求小于0 就在头部添加节点

        to_add = ListNode(val)
        curr = self.head  # 伪头节点
        # 0,... ,index-1
        for _ in range(index):
            # 指向下一节点,等同于指向索引节点,最大的索引= 长度-1
            curr = curr.next
        # 添加操作
        to_add.next = curr.next
        curr.next = to_add
        # 记录链表长度的变化
        self.size += 1 

以上是十分关键的操作,有了这一步,在头部添加节点在尾部添加节点功能调用这个函数就可以了。
接下来是获取 index 的值和在尾部添加节点,这里也有一些困惑:
获取 index 的值的for循环需要index + 1,而 在尾部添加节点 不需要,直接index,看看有啥差别?

获取 index 的值

因为这里的索引依旧是原链表的索引,不需要考虑加了伪头节点的链表。

    def get(self, index: int) -> int:
        if index < 0 or index >= self.size:
            return -1
        curr = self.head
        for _ in range(index+1): # 例子:index=0
            curr = curr.next
        return curr.val

删除索引处节点

    def deleteAtIndex(self, index: int) -> None:
        if index < 0 or index >= self.size: return # 为啥是index >= self.size
        self.size -= 1
        pre = self.head
        for _ in range(index): # 指针指向它的前一个节点
            pre = pre.next
        curr = pre.next
        pre.next = curr.next

我们的目标是当前节点,拜拜了~
综上,问题解决。

报错

AttributeError: ‘NoneType’ object has no attribute ‘val’

通过检查,发现索引超过范围,但是还是调用了curr.next,细想一下,None怎么会有next 或者val的属性?
解决方法:检查索引范围设定。

链表相关题型

移除元素

在链表中删除节点,就要知道删除的节点的前一个节点。对于头节点来说,它没有前一个节点,为了方便编程,添加一个伪头节点,让头节点的操作与其他节点的操作一样,是一个不错的方法。

# Definition for singly-linked list.
# class ListNode:
# def \_\_init\_\_(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
    def removeElements(self, head: ListNode, val: int) -> ListNode:
    	# 伪头节点 
        dummy = ListNode(next=head)
        cur = dummy
        while (cur.next!=None):


**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化学习资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618317507)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值