python链表如何储存_VOL.2 如何在python中实现链式存储结构

一、前言

链式存储作为一种重要的数据存储方式有着极强的数据组织能力、灵活型和动态性,在众多数据结构中应用非常广泛。所谓链式存储结构,就是采用分散的存储空间分别存储每一组数据再通过地址链接的形式将全部数据组织到一起,这在C/C++语言中非常容易实现,因为他们有一个非常强大的工具——指针。指针虽然强大但也常常是劝退C语言入门者的一大杀器,作为最易入门的语言,python在程序员层面放弃了类似于指针的相关操作和地址的相关概念,没有了指针,我们该如何实现链式存储结构呢?

我个人认为,python作为一款不需要编程者显示地定义数据类型的编程语言,我们可以利用其面向对象的特性及其数据类型的灵活性和多样性,更加简单的实现链式存储结构。在这里,我以最基础的链式存储结构——单链表简单做一下介绍。

二、简单可行性分析

我们类比C语言中实现链式结构的方式来尝试在python中能否实现。

在C语言中,我们使用结构体来定义链表中的节点类型,每一个节点中包含一个数据域用来存储数据和一个地址域用来链接下一个节点。

typedef struct LinkList {

ElemType data;

LinkList* next;

}LNode;

而在python中,“类”可以实现类似于C语言结构体的功能,因此我们定义一个节点类。同样的,类中包含两个属性,一个是用来存储数据的数据域和一个用来存储下一个节点的节点域。

class LinkListNode:

def __init__(self):

# 在这里给每一个属性赋初始值,避免在初始化对象时出现问题

# 同样的也可以添加其他的地址域来实现二叉链表、双链表等链表

self.data = 0

self.next = None

接下来我们手动链接几个节点来试一试这种类定义的可行性。

# 这里初始化三个LinkListNode类对象,其中head_node为头节点

head_node = LinkListNode()

node1 = LinkListNode()

node2 = LinkListNode()

# 这里我们依次将三个节点对象链接在一起

head_node.next = node1

node1.next = node2

# 为了验证链接是否成功,我们将node2的数据域改为10,并通过头节点来访问它

node2.data = 10

data = head_node.next.next.data

print(data)

可以看到,我们成功的通过头节点访问到了第三个节点并打印了其数据域的值。也就是说,我们通过上述定义类方式,实现了节点的链接,也就是在python中实现链式存储结构是完全可行的。

三、链表的几个常用操作的实现

因为没有单独定义头节点的类,所以头节点对象同样拥有数据域,我利用该数据域来存储链表的长度,并在某些功能里加以利用。判断链表是否为空

def if_empty(head):

if head.next is None:

return True

else:

return False

由于头节点的数据域存储链表的长度,所以下面这种方法也是完全可行的

def if_empty(head):

if head.data == 0:

return True

else:

return False

2.遍历链表

def traversal(head):

if head.next is None:

print("Error! LinkList is empty!")

else:

node = head.next

while node is not None:

print(node.data, end=' ')

node = node.next

3.在任意位置添加一个数据域值为data的节点

def add_node(head, data, location=-1):

# 检查添加的位置是否合法,其中-1代表表尾

if location > head.data + 1 or (location <= 0 and location != -1):

print("Input position exception, add failed!")

else:

node = LinkListNode()

pre_node = head

node.data = data

order = 1

if 1 <= location <= head.data:

# 如果添加的节点位置不在表尾,需要改动两个节点的next值

while order != location:

pre_node = pre_node.next

order += 1

node.next = pre_node.next

pre_node.next = node

else:

# 如果添加的节点位于表尾,只需要改变尾节点的next值

pre_node = head

while pre_node.next is not None:

pre_node = pre_node.next

pre_node.next = node

head.data += 1

4.删除任意位置的节点

def pop_node(head, location=-1):

# 检删除的位置是否合法,-1代表表尾

if location > head.data or (location <= 0 and location != -1):

print("Input position exception, pop failed!")

else:

pre_node = head

order = 1

if 1 <= location < head.data:

# 如果删除的节点位置不在表尾,需要改动两个节点的next值

while order != location:

pre_node = pre_node.next

order += 1

data = pre_node.next.data

pre_node.next = pre_node.next.next

else:

# 如果删除的节点位于表尾,只需要改变尾节点的next值

# 这里要注意,如果直接将表尾节点置为None,python会理解为新建一个值为Node的变量

# 所以只能找到前驱节点,然后将前驱节点的next置为Node

pre_node = head

while pre_node.next.next is not None:

pre_node = pre_node.next

data = pre_node.next.data

pre_node.next = None

head.data -= 1

return data

其他的功能,例如访问某个节点的数据域,都可以用相关代码实现,这里就不在赘述。

四、总结

这里只展示了单链表的相关操作,但是如上文定义节点类时注释中所说,通过更改类中属性的定义,完全可以实现双链表、循环链表、二叉链表等所有常用的链式存储结构。另外也可以更改本文中展示的单链表中增加节点和删除节点等操作来实现栈和队列。

个人理解,如有错误,请及时指出!谢谢!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值