Loading

Python实现链表

链表是用指针连接的用于存储数据的数组,它最大的优点在于可以有效利用零碎的内存空间。在很多语言中,数组的大小要提前定义,定义后不能随便修改,而且数组中只能存储同一类型的变量,使用链表可以改变数组的长度,并且可以存储不同类型的数据,在Python中使用列表模拟链表。

1. 单链表

链表的每个元素不仅仅存储这个元素的值,还要存储与它相连的元素的指针的值,这样链表才能被连起来。单链表的每个元素包含一个本身的值和一个指向下一个数的指针。因为链表的最后一个数没有下一个数,所以它的指针为空指针,在程序中可以将其置为-1

graph LR 1-->2 2-->3 3-->5 5-->6 6-->7

使用两个列表来分别存储元素和指针的值,输出单链表的值

# 输出单链表
ListValue = [1, 5, 6, 2, 7, 3]
ListRight = [3, 2, 4, 5, -1, 1]
head = 0
print(ListValue[head])
next = ListRight[head]
while next != -1:
    print(ListValue[next])
    next = ListRight[next]

2. 双链表

双链表中的每个元素是由它的值和两个指针组成的,一个指针指向下一个元素,一个指针指向上一个元素。

graph LR 1-->2-->1 2-->3-->2 3-->5-->3 5-->6-->5 6-->7-->6

双向输出双链表的值

# 双向输出双链表
ListValue = [1, 5, 6, 2, 7, 3]
ListRight = [3, 2, 4, 5, -1, 1]
ListLeft = [-1, 5, 1, 0, 2, 3]
print('-------正向输出--------')
head = ListLeft.index(-1)
print(ListValue[head])
next = ListRight[head]
while next != -1:
    print(ListValue[next])
    next = ListRight[next]

print('------反向输出-------')
head = ListRight.index(-1)
print(ListValue[head])
next = ListLeft[head]
while next != -1:
    print(ListValue[next])
    next = ListLeft[next]

3. 单链表添加元素

给定一个元素,确定它要插入的位置(要求已知插入位置前面一个元素的位置)

  • 将新元素指向要插入位置的后面一个元素
  • 将要插入位置的前面一个元素指向新元素
graph LR 1-->2-->3-->5-->6-->7 4

首先将新元素指向要插入位置的下一个元素

graph LR 1-->2-->3-->5-->6-->7 4-->5

将要插入位置的前面一个元素指向新元素

graph LR 1-->2-->3-.-5-->6-->7 3-->4-->5
# 单链表添加一个元素
# 定义一个输出链表的函数
def Output(ListValue, ListRight, head):
    print(ListValue[head])
    next = ListRight[head]
    while next != -1:
        print(ListValue[next])
        next = ListRight[next]

ListValue = [1, 5, 6, 2, 7, 3]
ListRight = [3, 2, 4, 5, -1, 1]
head = 0
prepos = 5   # 插入的位置的上一个元素的位置

Output(ListValue, ListRight, head)
print('------------------')

# 单链表添加元素,需要已知要插入的位置的上一个元素的位置
ListValue.append(4)    # 插入数
ListRight.append(ListRight[prepos])    # 插入指针
ListRight[prepos] = len(ListValue) - 1    # 改变指针指向
Output(ListValue, ListRight, head)

4. 双链表中添加元素

类似于单链表添加元素

  • 先给新元素的左右指针赋值
  • 再给前面元素的右指针、后面元素的左指针赋值
graph LR 1-->2-->1 2-->3-->2 3-->5-->3 5-->6-->5 6-->7-->6 4

先给新元素的左右指针赋值

graph LR 1-->2-->1 2-->3-->2 3-->5-->3 5-->6-->5 6-->7-->6 4-->3 4-->5

再给前面元素的右指针、后面元素的左指针赋值

graph LR 1-->2-->1 2-->3-->2 5-->6-->5 6-->7-->6 4-->3-->4 4-->5-->4 3-.-5-.-3
# 向双链表中添加元素
def Output(ListValue, ListRight, head):
    print(ListValue[head])
    next = ListRight[head]
    while next != -1:
        print(ListValue[next])
        next = ListRight[next]

ListValue = [1, 5, 6, 2, 7, 3]
ListRight = [3, 2, 4, 5, -1, 1]
ListLeft = [-1, 5, 1, 0, 2, 3]

head = 0     # 确定第一个元素的位置
prepos = 5   # 插入的位置的上一个元素的位置

Output(ListValue, ListRight, head)
print('------------------')

# 单链表添加元素,需要已知要插入的位置的上一个元素的位置
ListValue.append(4)    # 插入数
ListRight.append(ListRight[prepos])    # 插入指针
ListLeft.append(ListLeft[ListRight[prepos]])
# 或 ListLeft.append(prepos)
ListRight[prepos] = len(ListValue) - 1    # 改变指针指向
ListLeft[ListRight[prepos]] = len(ListValue) - 1
Output(ListValue, ListRight, head)

5. 删除单链表中的元素

将删除元素所在位置的前面元素的指针指向删除元素位置后面元素的位置

graph LR 1-->2-->3-->5-->6-->7
graph LR 1-->2-->3-.-5-->6-->7 3-->6
# 删除单链表中的一个元素
def Output(ListValue, ListRight, head):
    print(ListValue[head])
    next = ListRight[head]
    while next != -1:
        print(ListValue[next])
        next = ListRight[next]

ListValue = [1, 5, 6, 2, 7, 3]
ListRight = [3, 2, 4, 5, -1, 1]
head = 0
prepos = 5   # 插入的位置的上一个元素的位置

Output(ListValue, ListRight, head)
print('------------------')

ListRight[prepos] = ListRight[ListRight[prepos]]
Output(ListValue, ListRight, head)

6. 删除双链表中的元素

  1. 将删除元素所在位置的前面元素的右指针指向删除元素位置后面元素的位置
  2. 将删除元素所在位置的后面元素的左指针指向删除元素位置前面元素的位置
graph LR 1-->2-->1 2-->3-->2 3-->5-->3 5-->6-->5 6-->7-->6
graph LR 1-->2-->1 2-->3-->2 3-.-5-->3 5-->6-.-5 6-->7-->6 3-->6-->3
# 双链表中删除一个元素
def Output(ListValue, ListRight, head):
    print(ListValue[head])
    next = ListRight[head]
    while next != -1:
        print(ListValue[next])
        next = ListRight[next]

ListValue = [1, 5, 6, 2, 7, 3]
ListRight = [3, 2, 4, 5, -1, 1]
ListLeft = [-1, 5, 1, 0, 2, 3]

head = 0     # 确定第一个元素的位置
prepos = 5   # 插入的位置的上一个元素的位置

Output(ListValue, ListRight, head)
print('------------------')

ListRight[prepos] = ListRight[ListRight[prepos]]
ListLeft[ListRight[ListRight[prepos]]] = prepos

Output(ListValue, ListRight, head)

刚开始用mermaid在markdown里画流程图 ,画得太丑了,请见谅😭

来源:《你也能看得懂的 Python 算法书

posted @ 2021-05-29 20:34  紫曜花  阅读(494)  评论(0)    收藏  举报