单链表反转

链表的准备,构建四个节点的单链表,表头是phead:

class Node:
    def __init__(self, val):
        self.val = val
        self.next = None

nodeList = [Node(1),Node(2),Node(3),Node(4)]
phead = nodeList[0]
for i in range(len(nodeList)-1):
    nodeList[i].next = nodeList[i+1]
p = phead
while p is not None:
    print(p.val)
    p = p.next

递归的方法翻转链表。记输入链表是L0=phead+L1。既然用递归,则函数的输入是L0的表头phead,输出是新链表的表头,即L0的尾节点。内部调用自身的语句的输入应该是L1,其输出是L1的尾结点,也是L0的尾结点,新的表尾也就是L0的表头指向None。可知新链表的表头从递归的最深层,一路传送到最上层。亦可知,之后需要处理链表与子链表的衔接,即phead.next.next = phead; phead.next = None,L1的原表头即phead.next要指向phead。:

def reverseL(phead):
    if phead is None or phead.next is None:
        return phead
    
    node = reverseL(phead.next)
    phead.next.next = phead
    phead.next = None
    return node

非递归的方法翻转链表。

  • 递归和非递归两种翻转方法,对输入的检测都是一样的逻辑if not phead or not phead.next: return phead
  • 每次循环,都要拿到前两个节点的指针p和q,循环以q.next的存在性判断是否终止
  • 更新p,q和连接时需要一个临时节点指针
def reverseL(phead):
    if not phead or not phead.next:
        return phead
    p, q = phead, phead.next # 每次循环,要有前两个节点的指针
    while True:
        if q.next:
            temp = q # 临时变量
            q = q.next
            temp.next = p #
            p = temp
        else:
            q.next = p
            break
    phead.next = None
    return q

你可能感兴趣的:(算法学习)