计算机基础:21、计算机基础实践-双向链表数据结构、FIFO算法、LRU算法

计算机基础:21、计算机基础实践-双向链表数据结构、FIFO算法、LRU算法

单向链表与双向链表的简介

在这里插入图片描述
在这里插入图片描述

双向链表数据结构

在这里插入图片描述
下方的代码实现了上图中的功能(双向链表数据结构)

# node类表示在链表中的节点
class Node:
	def __init__(self, key, value):
		self.key = key
		self.value = value
		self.prev = None # 用于存储上一个节点
		self.next = None # 用于存储下一个节点
	
	def __str__(self):
		val = '{%d: %d}' % (self.key, self.value)
		return val

	def __repr__(self):
		val = '{%d: %d}' % (self.key, self.value)
		return val

# 双向链表
class DoubleLinkedList:
	def __init__(self, capacity=0xffff):
		self.capacity = capacity
		self.head = None # 链表头部节点
		self.tail = None # 链表尾部节点
		self.size = 0 # 链表长度

	# 从头部添加节点
	def __add_head(self, node):
		if not self.head:
			# 当前链表中没有节点
			self.head = node
			self.tail = node
			self.head.next = None
			self.head.prev = None
		else:
			# 当前链表中有节点
			node.next = self.head
			self.head.prev = node
			self.head = node
			self.head.prev = None
		self.size += 1
		return node
		
	# 从尾部添加节点
	def __add_tail(self, node):
		if not self.tail:
			self.tail = node
			self.head = node
			self.tail.next = None
			self.tail.prev = None
		else:
			self.tail.next = node
			node.prev = self.tail
			self.tail = node
			self.tail.next = None
		self.size += 1
		return node
	
	# 从尾部删除
	def __del_tail(self):
		if not self.tail:
			return
		node = self.tail
		if node.prev:
			self.tail = node.prev
			self.tail.next = None
		else:
			self.tail = self.head = None
		self.size -= 1
		return node
	
	# 从头部删除
	def __del_head(self):
		if not self.head:
			return
		node = self.head
		if node.next:
			self.head = node.next
			self.head.prev = None
		else:
			self.tail = self.head = None
		self.size -= 1
		return node
		
	# 任意节点删除
	def __remove(self, node):
		# 如果node=None,默认删除尾部节点
		if not node:
			node = self.tail
		if node == self.tail:
			self.__del_tail()
		elif node == self.head:
			self.__del_head()
		else:
			node.prev.next = node.next
			node.next.prev = node.prev
			self.size -= 1
		return node
	
	# 弹出头部节点
	def pop(self):
		return self.__del_head()
	
	# 添加节点,默认往尾部添加
	def append(self, node):
		return self.__add_tail(node)

	# 往头部添加节点
	def append_front(self, node):
		return self.__add_head(node)

	# 删除节点(node为空则默认删除最后一个节点,否则删除指定节点)
	def remove(self, node=None):
		return self.__remove(node)
	
	# 打印当前链表
	def print(self):
		p = self.head
		line = ''
		while p:
			line += '%s' % p
			p = p.next
			if p:
				line += '=>'
		print(line)
	

if __name__ == '__main__':
	l = DoubleLinkedList(10)
	noees = []
	for i in range(10):
		node = Node(i, i)
		nodes.append(node)

	l.append(nodes[0])
	l.print()
	l.append(nodes[1])
	l.print()
	l.pop()
	l.print()
	l.append(nodes[2])
	l.print()
	l.append_front(nodes[3])
	l.print()
	l.append(nodes[4])
	l.print()
	l.remove(nodes[2])
	l.print()
	l.remove()
	l.print()

FIFO缓存置换算法(先进先出算法)

FIFO缓存置换算法,当需要淘汰缓存的时候,把最先进入链表的节点淘汰

class FIFOCache(object):
	def __init__(self,capacity):
		self.capacity = capacity
		self.size = 0
		self.map = {}
		self.list = DoubleLinkedList(self.capacity)

	# 获取缓存
	def get(self, key):
		if key not in self.map:
			return -1
		else:
			node = self.map.get(key)
			return node.value

	# 写入缓存
	def put(self, key, value):
		if self.capacity == 0:
			return
		if key in self.map:
			node = self.map.get(key)
			self.list.remove(node)
			node.value = value
			self.list.append(node)
		else:
			if self.size == self.capacity
				node = self.list.pop()
				del self.map[node.key]
				self.size -= 1
			node = Node(key, value)
			self.list.append(node)
			self.map[key] = node
			self.size += 1

		def print(self):
			self.list.print()

if __name__ == '__main__':
	cache = FIFOCache(2)
	cache.put(1, 1)
	cache.print()
	cache.put(2, 2)
	cache.print()
	print(cache.get(1))
	cache.put(3,3)
	cache.print()
	print(cache.get(2))
	cache.print()
	cache.put(4,4)
	cache.print()
	print(cache.get(1))

最近最少使用算法(LRU)

每次使用缓存的时候,把使用的缓存移到链表的最前面,需要淘汰的时候直接把链表尾部的节点淘汰即可
在这里插入图片描述
在这里插入图片描述

class LRUCache(object):
	def __init__(self, capacity):
		self.capacity = capacity
		self.map = {}
		self.list = DoubleLinkedList(self.capacity)

	def get(self, key):
		if key in self.map:
			node = self.map[key]
			self.list.remove(node)
			self.list.append_front(node)
			return node.value
		else:
			return -1
					
	def put(self, key, value):
		if key in self.map:
			node = self.map.get(key)
			self.list.remove(node)
			node.value = value
			self.list.append_front(node)
		else:
			node = Node(key,value)
			#缓存已满
			if self.list.size >= self.list.capacity:
				old_node = self.list.remove()
				self.map.pop(old_node.key)
				
			#缓存未满
			self.list.append_front(node)
			self.map[key] = node

	def print(self):
		self.list.print()

if __name__ == '__main__':
	cache = LRUCache(2)
	cache.put(2, 2)
	cache.print()
	cache.put(1,1)
	cache.print()
	cache.put(3,3)
	cache.print()
	print(cache.get(1))
	cache.print()
	print(cache.get(2))
	cache.print()
	print(cache.get(3))
	cache.print()
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值