python链表和树实验总结_关于Python实现树结构和链表结构的一点想法

关于Python实现树结构和链表结构的一点想法

Python由于内置的数据结构具有很高的灵活性,所以可以用很多种方式来构建树、图、链表等结构

1. 树的Python实现

python自然可以使用class来创建Node结点类和Trie类,然后通过left和right属性保存Node结点来实现树

Python也可以使用字典来嵌套生成树,字典的Key作为当前结点,字典的Value为子树。

但需要注意的是,字典的value是一个字典,那么这个value字典中可以有多个Key,那么每个Key之间是互相为兄弟关系的。

同理,如列表等数据结构,也可以通过嵌套来生成树

在使用字典创建树时,可以重复利用dict的方法setdefault(key,default),如果key存在,则返回value,若不存在,则插入key:default并返回default

--------------------------

比较有意思的是对于树而言,在哪里存他的数据会有很多的不同,对于不同场景酌情实现

假设是使用class实现的字母前缀树,那么可以把字母值保存在当前Node结点的value中,那么这样匹配一个单词的时候,需要遍历所有的子节点找到对应值是否存在,这样在某一层上就多花了k的时间(由于字典自带哈希,所以字典实现的前缀树查找会很快,是O(1)的时间)

也可以把字母值保存在连向子结点的连线上

由于字母前缀树每个结点最多只有26种取值,所以可以提前存一个初始化为26个None的列表,如果在b的位置有值,那么在第二个位置存子结点的Node,这样就实现了把字母值存在连向子结点的连线上。

同时,匹配一个单词的时候,直接来判断这个位置是None还是存在Node结点就可以直接找到下一个结点了,也是O(1)的时间,但是如果树很深,但是很窄的话,这样会浪费许多空间

所以针对不同的场景需求,可以自行选择存储数据的位置,有不同的效果。

利用字典实现树代码如下

#利用字典实现前缀树

trie = {}

# 建立字典实现的字母前缀树

for word in words:

cur = trie

for alpha in word:

cur=cur.setdefault(alpha,{})

2. 链表的Python实现

python本身的列表已经很好用了,在python的标准库中没有链接列表的实现,如果需要大量插入和删除还是需要手动实现一下的,可以实现O(k)的增删查找复杂度

链表实现自然也可以用class来创建Node结点类和Trie类,在Trie类中创建head与tail的Node对象,就可以进行追踪了

如果需要O(1)的查找以及增删复杂度的链表,那么需要配合哈希与双向链表实现、那么在Trie类中还需要添加一个dict哈希来进行节点位置的追踪,key为Node节点的Key(Node节点属性有Key、value、next、pre),Value为该Node节点

#配合哈希与双向链表实现O(1)的查找以及增删复杂度

class Node:

def __init__(self,key,value):

self.key=key

self.value=value

self.next=None

self.pre=None

class LRUCache:

def __init__(self, capacity: int):

self.dic=dict()

self.capacity=capacity

self.size=0

self.head=Node(-1,-1)

self.tail=Node(-1,-1)

self.head.next=self.tail

self.tail.pre=self.head

def get(self, key: int) -> int:

if(key in self.dic):

new_node = Node(key, self.dic[key].value)

# 删除旧节点

del_node = self.dic[key]

del_node.pre.next = del_node.next

del_node.next.pre = del_node.pre

# 添加新节点到头部

new_node.pre = self.head

new_node.next = self.head.next

self.head.next.pre = new_node

self.head.next = new_node

self.dic[key]=new_node

return self.dic[key].value

else:

return -1

def put(self, key: int, value: int) -> None:

new_node = Node(key, value)

# 添加新节点到头部

new_node.pre = self.head

new_node.next = self.head.next

self.head.next.pre = new_node

self.head.next = new_node

if(key in self.dic):

del_node=self.dic[key]

del_node.pre.next=del_node.next

del_node.next.pre=del_node.pre

else:

# 如果key不在链表中,才考虑删去尾元素或者更改size

if(self.size==self.capacity):

# 如果满了,要删去尾部节点

self.dic.pop(self.tail.pre.key)

self.tail.pre.pre.next=self.tail

self.tail.pre=self.tail.pre.pre

else:

self.size+=1

self.dic[key] = new_node

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值