python中没有链表这种数据类型,所以需要先定义ListNode

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

python获取A链接内容 python获取链表长度_删除节点


如果定义上图的链表,代码为:

l3 = ListNode(3,None)
l2 = ListNode(2,l3)
l1 = ListNode(1, l2)

debug中可查看,与我们预期的一样

python获取A链接内容 python获取链表长度_python获取A链接内容_02

从头到尾读取链表
def read_list(head):
    res = []
    while head:
        res.append(head.val)
        head = head.next
    return res

# 从头到尾读取链表
head = l1
res = read_list(head)
print(res)

结果为:[1, 2, 3]

从尾到头读取链表
# 从尾到头读取链表
def read_list_rev(head):
    res = []
    while head:
        res.insert(0, head.val)
        head = head.next
    return res

head = l1
res = read_list_rev(head)
print(res)

结果为:[3, 2, 1]

获取链表长度
# 获取链表长度
def list_len(head):
    length = 0
    while head:
        length += 1
        head = head.next
    return length

head = l1
length = list_len(head)
print(length)

结果为:3

清空链表
# 清空链表
def clear(head):
    head = None
    return head

head = l1
head = clear(head)
res = read_list(head)
print(res)

结果为:[]

追加节点

若第一个节点就为None,则直接赋值;
若第一个节点不为None,则找到最后一个节点,然后加在最后面。
要注意的是:

  1. 不能直接用head,要用个pre去索引,因为虽然我们追加是加在最后面,但是我们索引链表的话,还是需要从表头找起的,所以不能损坏表头;
  2. while处不能是pre,因为如果是pre的话,跳出while循环时就已经是指向最后一个节点的下一个节点的了,所以是while pre.next
# 追加节点
def node_append(head, new_node):
    if head is None:
        head = new_node
    else:
        pre = head
        while pre.next:
            pre = pre.next
        pre.next = new_node
    return head

head = l1
l4 = ListNode(4,None)
head = node_append(head, l4)
res = read_list(head)
print(res)

结果为:[1, 2, 3, 4]

获取节点

要注意的是index的正负,若为-1即为倒数第一个,所以需要list_len(head)+index

# 获取节点
def get_node(head, index):
    if index>=0:
        index=index
    else:
        index = list_len(head)+index
    while index:
        head = head.next
        index -= 1
    return head
    
head = l1
index = -1
head = get_node(head, index)
res = read_list(head)
print(res)

head = l1
index = 1
head = get_node(head, index)
res = read_list(head)
print(res)

结果为:
受上一题的影响所以会有4
[4][2, 3, 4],为什么会输出三个数?因为在这里会获取index为1的节点,而不是index为1的节点值,所以当read_list的时候会后面所有节点的值读出来。

设置节点
# 设置节点
def set_node(head, index, val):
    if index>=0:
        index=index
    else:
        index = list_len(head)+index

    pre = head
    while index:
        pre = pre.next
        index -= 1
    pre.val = val
    return head

head = l1
index = 1
val = 5
head = set_node(head, index, val)
res = read_list(head)
print(res)

结果为:[1, 5, 3, 4]

插入节点

要注意边界值的判断!

# 插入节点
def node_insert(head, index, new_node):
    # 长度边界值判断
    if abs(index+1) > list_len(head):
        return False

    # 特殊位置判断
    if index == 0:
        new_node.next = head
        head = new_node
    else:
        if index > 0:
            index = index
        else:
            index = list_len(head) + index

        # 找到插入位置的上一个节点
        pre = head
        index -= 1
        while index:
            pre = pre.next
            index -= 1
        new_node.next = pre.next
        pre.next = new_node
    return head

head = l1
index = 2
l6 = ListNode(6,None)
head = node_insert(head, index, l6)
res = read_list(head)
print(res)

结果为:[1, 5, 6, 3, 4] 出现5是因为上一题的原因导致
上述代码中也可以调用get_node来减少重复功能的代码

删除节点

越到后面,临界判断越多!

# 删除节点
def del_node(head, index):
    if index>=0:
        index=index
    else:
        index = list_len(head)+index

    # 特殊情况判断
    if abs(index+1) > list_len(head):
        return False
    elif index == 0:
        head = None
    else:
        # 找到删除位置的上一个节点
        pre = head
        index -= 1
        while index:
            pre = pre.next
            index -= 1
        node_next = pre.next
        pre.next = node_next.next
    return head

head = l1
index = 1
head = del_node(head, index)
res = read_list(head)
print(res)

结果为:
删除前:[1, 5, 6, 3, 4] 删除后:[1, 6, 3, 4]

反转链表

特殊情况:表头为None或者只有一个节点
这里需要三个节点同时存储:pre指向一个节点的地址,head指向当前节点的地址,tmp指向下一节点的地址。

# 反转链表
def rev_node(head):
    # 特殊情况判断
    if head is None or head.next is None:
        return head

    pre = None
    while head:
        tmp = head.next
        head.next = pre
        pre = head
        head = tmp
    return pre

结果为:[4, 3, 6, 1]

部分代码参考:

完整代码
class ListNode:
    def __init__(self, x, next):
        self.val = x
        self.next = next

l3 = ListNode(3, None)
l2 = ListNode(2, l3)
l1 = ListNode(1, l2)


# 从头到尾读取链表
def read_list(head):
    res = []
    while head:
        res.append(head.val)
        head = head.next
    return res

head = l1
res = read_list(head)
print(res)


# 从尾到头读取链表
def read_list_rev(head):
    res = []
    while head:
        res.insert(0, head.val)
        head = head.next
    return res

head = l1
res = read_list_rev(head)
print(res)


# 获取链表长度
def list_len(head):
    length = 0
    while head:
        length += 1
        head = head.next
    return length

head = l1
length = list_len(head)
print(length)


# 清空链表
def clear(head):
    head = None
    return head

head = l1
head = clear(head)
res = read_list(head)
print(res)


# 追加节点
def node_append(head, new_node):
    if head is None:
        head = new_node
    else:
        pre = head
        while pre.next:
            pre = pre.next
        pre.next = new_node
    return head

head = l1
l4 = ListNode(4,None)
head = node_append(head, l4)
res = read_list(head)
print(res)


# 获取节点
def get_node(head, index):
    if index>=0:
        index=index
    else:
        index = list_len(head)+index
    while index:
        head = head.next
        index -= 1
    return head
head = l1
index = -1
head = get_node(head, index)
res = read_list(head)
print(res)


head = l1
index = 1
head = get_node(head, index)
res = read_list(head)
print(res)


# 设置节点
def set_node(head, index, val):
    if index>=0:
        index=index
    else:
        index = list_len(head)+index

    pre = head
    while index:
        pre = pre.next
        index -= 1
    pre.val = val
    return head

head = l1
index = 1
val = 5
head = set_node(head, index, val)
res = read_list(head)
print(res)


# 插入节点
def node_insert(head, index, new_node):
    if index>=0:
        index=index
    else:
        index = list_len(head)+index

    # 长度边界值判断
    if abs(index+1) > list_len(head):
        return False

    # 特殊位置判断
    if index == 0:
        new_node.next = head
        head = new_node
    else:
        # 找到插入位置的上一个节点
        pre = head
        index -= 1
        while index:
            pre = pre.next
            index -= 1
        new_node.next = pre.next
        pre.next = new_node
    return head

head = l1
index = 2
l6 = ListNode(6,None)
head = node_insert(head, index, l6)
res = read_list(head)
print(res)


# 删除节点
def del_node(head, index):
    if index>=0:
        index=index
    else:
        index = list_len(head)+index

    # 特殊情况判断
    if abs(index+1) > list_len(head):
        return False
    elif index == 0:
        head = None
    else:
        # 找到删除位置的上一个节点
        pre = head
        index -= 1
        while index:
            pre = pre.next
            index -= 1
        node_next = pre.next
        pre.next = node_next.next
    return head

head = l1
index = 1
res = read_list(head)
print(res)
head = del_node(head, index)
res = read_list(head)
print(res)


# 反转链表
def rev_node(head):
    # 特殊情况判断
    if head is None or head.next is None:
        return head

    pre = None
    while head:
        tmp = head.next
        head.next = pre
        pre = head
        head = tmp
    return pre

head = l1
res = read_list(head)
print(res)
head = rev_node(head)
res = read_list(head)
print(res)