单向链表反转(python)
1.什么是链表,跟列表相比是什么样的?
链表是一种物理存储单元上非连续(存储单元可以是离散的)、非顺序(使用链表存储的数据元素,其物理存储位置是随机的)的存储结构;而列表就是连续性存储的数据。
2.链表的基本存储单元:节点(Node)
每个节点包含存储数据的数据存储空间和存储地址的指针空间
代买如下:
class Node:
def __init__(self,data = None, next = None):
self.data = data
self.next = next
3.单向链表:
链表分为单向链表和双向链表,双向链表和单向链表的区别就在于双向链表其节点的地址存储区存放着两个指针数据,即一个指针(pre)是指向其前一个节点,另一个指针(next)是指向其后一个节点。单向链表的地址存储区仅存放着一个指向其下一个节点的指针(next),就好像是有一根链子,你只能从头顺着一个方向找它的节点,而双向连表可以顺着两个方向进行查找。
class LinkedList():
def __init__(self): #初始化链表,默认为空链表
self._head = Node()
self._tail = None
4.头指针和头节点
在这里必须说明一下,我看了这么多的链表的博客和说明,越看越糊涂,尤其是,链表的头指针(Head),有不少人直接将头指针描述成这种:
当然只要能描述清楚,每个人都有自己的方式,但是我总觉得这种描述方式有很多模棱两可的地方:
1)模型中Head的指向链表第一个节点(头节点)的箭头很容易让人理解成头指针Head.next,在C语言中内存地址就是指针,其实,Head在这里就是头指针,且其”存储地址“存储的就是链表第一个节点的地址,即头指针指向了头节点。
2)如果能明白我在1)中所说的意思,就不会将链表的第一个节点A1描述成Head.next,而是直接将Head理解成第一个节点A1。
其实这种歧义,归根到底是是我个人的语言基础差,不多说,都是泪。为了避免这种莫名其妙的理解误差,我重新又将单向链表的模型描述成这种形式:
我个人觉得,这种描述方式更容易理解python中的链表数据结构:1)黄色的字体并非存储空间中存在的而是抽象意义上的链表数据结构,即所谓的单向链表Head–>A1–>A2–>A3–>None;
2)褐色字体及图框所描述的则是实际意义上存储空间中具体的链表数据。
5.链表的尾节点:
单向链表的尾节点一定是指向None的,也就是说最后一个节点中的地址存储空间中的地址为None。
6.单向链表反转
通过LinkedList()类进行创建链表并往链表中添加节点;
这里假设我们获得了链表为pHead的链表,对该链表进行反转并输出其头节点:
class Solution()
def reverse(self,pHead):
cur = pHead #找到链表的第一个节点
pTail = None #新建一个空链表
while cur:
temp = cur.next #step1
cur.next = pTail #step2
pTail = pHead #step3
cur = temp #step4
return pTail
其中关键的四步:
step1:
将暂存地址temp指向第二个节点A2及其后面的节点,相当于新建一个以第二个节点开头的新链表;
step2:
将第一个节点的下一个节点指向pTail = None,此时链表pHead仅包含第一个节点和尾巴None
step3:
将更新后的链表pHead"赋值给"链表pTail,事实上是将链表pTail头指针指向链表pHead的头指针。
step4:
将pHead的头指针指向新链表temp,相当于更新了一次pHead,将第一个节点删掉了
按照这四个步骤,不断循环,知道pHead只剩下尾巴,此时的pTail中的节点元素恰好是逆序的,将其输出。
总结:
1)单向链表的”指针“总是指向下一个链表节点;
2)链表的头指针可以认为是其第一个节点
小白出身,请大家批评指点!