前言
先复习一下几种数据结构吧。
链表,就是一个个结点,用指针的方式来连接起来,因为py的语言特点,我们只需要将next赋值为下一个对象的变量名即可。(变量名本身就可以理解成一个指针索引)
如果链表还有问题,看这里。
队列和栈,前两天用list实现了一个,在这里,也有讲解。
一个是first in first out,另一个是first in last out。
双向队列,就是两端都能插入删除的队列,这个的实现需要双向链表。
循环队列,之前是list实现的,这里我们用一次node,结构基于循环链表。
双向链表和循环链表在这里,都是讲过的,不再赘述。
实现链表
没有链表,我们都做不了。
链表的本质上就是一个个的结点么, 所以这里我先给出了结点的定义。
class _Node():
"""lightweight,nonpublic class for storing linked node"""
__slots__ = '_element','_next'
def __init__(self,element,next):
self._element = element
self._next = next
他那个__slots__对象,貌似是能节省一个dict,正常直接创建两个变量也是一样的。
我们将这个类放在整体的大类中就可以了。
栈:
class LinkedStack():
# 使用链表实现栈,链表第一项为栈顶,没有头节点
class _Node():
"""lightweight,nonpublic class for storing linked node"""
__slots__ = '_element','_next'
def __init__(self,element,next):
self._element = element
self._next = next
def __init__(self):
"""create an empty stack"""
self._head = None
self._size = 0
def __len__(self):
"""return the number of elementsin the stack"""
return self._size
def is_empty(self):
"""return true if the stack is empty"""
return self._size==0
def push(self,e):
"""add an element e to the top of the stack"""
self._head = self._Node(e,self._head)
self._size += 1
def top(self):
"""return(but not remove) the element at the top of the stack"""
if self.is_empty():
raise Empty('stack is empty')
return self._head._element
def pop(self):
"""remove and return the element from the top of the stack"""
if self.is_empty():
raise Empty('stack is empty')
answer = self._head._element
self._head = self._head._next
self._size -= 1
return answer
队列:
class LinkedQueue():
# 使用node节点实现队列,链表头是队首
class _Node():
"""lightweight,nonpublic class for storing a singly linked node"""
__slots__ = '_element','_next'
def __init__(self,element,next):
self._element = element
self._next = next
def __init__(self):
"""create an empty queue"""
self._head = None
self._tail = None
self._size = 0
def __len__(self):
"""return the length of elements in the queue"""
return self._size
def is_empty(self):
"""return true if the queue is empty"""
return self._size == 0
def first(self):
"""return but not remove the element at the front of the queue"""
if self.is_empty():
raise Empty('queue is empty')
return self._head._element
def dequeue(self):
"""remove and return the first element of the queue"""
if self.is_empty():
raise Empty('queue is empty')
answer = self._head._element
self._head = self._head._next
self._size -= 1
if self.is_e():
self._tail = None
return answer
def enqueue(self,e):
"""add an element to the back of queue"""
newset = self._Node(e,None)
if self.is_empty():
self._head = newset
else:
self._tail._next = newset
self._tail = newset
self._size += 1
循环队列
基于循环链表,本质上就是将之前链表的tail.next = head,和head接上。
这样我们只使用一个tail存储就能遍历整个链表。
注意最开始没有对象,添加第一个对象时,既是队首也是队尾。
如果是只有一个对象,pop之后tail=none
代码:
class CircularQueue():
"""queue implementation using circularly linked list for storage"""
class _Node():
"""lightweight,nonpublic class for storing a singly linked node"""
__slots__ = '_element','_next'
def __init__(self,element,next):
self._element = element
self._next = next
def __init__(self):
"""create an empty queue"""
self._tail = None
self._size = 0
def __len__(self):
"""return the number of elements in the queue"""
return self._size
def is_empty(self):
"""return true if the queue is empty"""
return self._size==0
def first(self):
"""return but not remove the element at the front of the queue"""
if self.is_empty():
raise Empty('queue is empty')
head = self._tail._next
return head._emelent
def dequeue(self):
"""remove and return the first element of the queue"""
if self.is_empty():
raise Empty('queue is empty')
oldhead = self._tail._next
if self._size == 1:
self._tail = None
else:
self._tail._next = oldhead._next
self._size -= 1
return oldhead._element
def enqueue(self,e):
"""add a element to the back of the queue"""
newest = self._Node(e,None)
if self.is_empty():
newest._next = newest
else:
newest._next = self._tail._next
self._tail._next = newest
self._tail = newest
self._size += 1
def rotate(self):
"""rotate front element to the back of the queue"""
# 这是一个遍历的方法,相当于__next__()
if self._size > 0:
self._tail = self._tail._next
双向链表
双向链表其实和单向差的不多,主要是每一个都有两个指针,所以插入删除麻烦一点,再就是注意边界条件
先实现一个双向链表:(因为是给双向队列服务的,所以用了私有变量形式)
我们实现的双向链表是有头节点和尾节点的!
class _DoublyLinkedBase():
"""a base class poviding a boubly linked list representation"""
class _Node():
__slots__ = '_element','_prev','_next'
def __init__(self,element,prev,next):
self._element = element
self._prev = prev
self._next = next
def __init__(self):
"""create a empty list"""
# 创建头尾结点并初始化
self._header = self._node(None,None,None)
self._trailer = self._Node(None,None,None)
self._header._next = self._trailer
self._trailer._prev = self._header
self._size = 0
def __len__(self):
"""return the number of elements in the list"""
return self._size
def is_empty(self):
"""return true if the list is empty"""
return self._size==0
def _insert_between(self,e,predecessor,successor):
"""add element e between pre and suc"""
newest = self._Node(e,predecessor,successor)
predecessor._next = newest
successor._prev = newest
self._size += 1
return newest
def _delete_node(self,node):
"""delete nonsentinel node from the list and return its element"""
predecessor = node._prev
successor = node._next
predecessor._next = successor
successor._prev - predecessor
self._size -= 1
element = node._element
# be helpful for python to delete the node
node._prev = node._next = node._element = None
return element
双向队列
这样我们的双向队列就方便了很多,代码:
class LinkedDeque(_DoublyLinkedBase):
"""double-ended queue implementation based on a doubly linked list"""
def first(self):
"""return but not remove the element at the front of the deque"""
if self.is_empty():
raise Empty('queue is empty')
return self._header._next._element
def last(self):
"""return but not remove the element at rhe back of the deque"""
if self.is_empty():
raise Empty('queue is empty')
return self._trailer._prev._element
def insert_first(self,e):
"""add an element to the front of the deque"""
self._insert_between(e,self._header,self._header._next)
def insert_last(self,e):
"""add an element to the back of the deque"""
self._insert_between(e,self._trailer._prev,self._trailer)
def delete_first(self):
"""remove and return the element from the front of the deque"""
if self.is_empty():
raise Empty('deque is empty')
return self._delete_node(self._header._next)
def delete_last(self):
"""remove and return the element from the back of the deque"""
if self.is_empty():
raise Empty('deque is empty')
return self._delete_node(self._trailer._prev)
这篇博客介绍了如何使用Python实现链表数据结构,包括栈、队列、循环队列和双向队列。首先回顾了链表的基本概念,然后详细阐述了每个结构的实现原理,特别提到了在实现双向队列时利用了双向链表的特性。文章提供了具体的代码示例来帮助理解。

1515

被折叠的 条评论
为什么被折叠?



