09月11, 2019

不用面向对象,实现单向链表(2)

上集回顾

上一节我们实现了链表的 Node 创建相关的函数

create_node(data, next)

以后我们将直接使用这个函数来创建链表的节点 Node,而非直接用 Dic 表示节点。

使用函数的意义 函数一方面将一组相关的逻辑封装在一起,减少重复编码,更重要的是对逻辑细节的抽象,用简短的函数名指代一系列逻辑。 比如人们会说 “我去做饭了”,而不会说 “我去把菜从冰箱拿出来,走到洗菜池··· ··· 最后把炒好的菜端出来给你吃”。这里 “做饭” 的表达就是做饭过程的抽象,提升了语言表达的效率。

一个节点,一个节点,穿成串!

链表的基石是 Node,我们已经拥有了创建节点的能力,下来就是如何将它们组合在一起构成链表。 上一节已经讲过 Node 的格式:

title

单独的节点意义不大,只有多个 Node 连接在一起才能构成链表。节点之间通过各自的 next 字段关联起来,连接到一起的节点们看起来类似这样。

title

从节点到链表的蜕变,关键就在于节点之间如何建立连接。

建立连接

每个节点的 next 字段,就是用来表示下一个节点的引用^1^。建立从 Node1 到 Node2 的联系,实际上是设置 Node1 的 next 字段,指向 Node2,在 Python 中,直接将 Node2 赋值给 Node1['next'] 即可。

def set_next_node(cur_node, next_node):
    cur_node['next'] = next_node

# 顺便实现获取下一个节点的函数
def get_next_node(cur_node):
    return cur_node['next']

简单的测试

我们用已经实现的函数,创建 3 个节点,并将他们依次串联起来,这就是链表的雏形了。

# 创建 3 个节点
node1 = create_node("#Node 1")
node2 = create_node("#Node 2")
node3 = create_node("#Node 3")

# 依次连接
set_next_node(node1, node2)
set_next_node(node2, node3)
# 上面图中 3 个节点之间的关系已经实现

# 试着打印 node1 的下一个节点的数据,应该是 #Node2
next_node = get_next_node(node1)
print(next_node['data'])

# 打印再下一个节点,应该是 #Node3
next_node = get_next_node(next_node)
print(next_node['data'])

输出如下

$ python test3.py 
#Node 2
#Node 3

链表怎么表示?

现在的链表依然需要依赖节点表示,没有面向对象技术,链表本身如何表达?我们下一节继续。

引用^1^ 在 python 中,所有的变量,都是值的引用。如果有 C/C++ 编程经验的同学,可以将所有的变量理解为 void * 类型,它们都指向对应类型的 对象(python3 中)。所以节点里所谓的“下一个节点的引用”,直接使用下一节点赋值到“下一个节点”就可以了。

本文链接:http://www.thinkinpython.com/post/singly_link_list_2.html

-- EOF --