栈的实现
栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。
class Stack(object):
def __init__(self, limit=10):
self.stack = [] # 存放元素
self.limit = limit # 栈容量极限
def push(self, data):
# 判断栈是否溢出
if len(self.stack) >= self.limit:
raise IndexError('超出栈容量极限')
self.stack.append(data)
def pop(self):
if self.stack:
return self.stack.pop()
else:
# 空栈不能被弹出元素
raise IndexError('pop from an empty stack')
def peek(self):
# 查看栈的栈顶元素(最上面的元素)
if self.stack:
return self.stack[-1]
def is_empty(self):
# 查看堆栈的最上面的元素
return not bool(self.stack判断栈是否溢)
def size(self):
# 返回栈的大小
return len(self.stack)
链表的实现
链表(linked_list)是物理存储单元上非连续的、非顺序的存储结构,数据元素的逻辑顺序是通过链表的指针地址实现,每个元素包含两个结点,一个是存储元素的数据域 (内存空间),另一个是指向下一个结点地址的指针域。根据指针的指向,链表能形成不同的结构,例如单链表,双向链表,循环链表等。
单链表
class Node:
def __init__(self, data):
self.data = data
self.next = None
class Linked_List:
def __init__(self, head=None):
self.head = head
def append(self, new_element):
"""
在链表后面增加一个元素
"""
current = self.head
if self.head:
while current.next:
current = current.next
current.next = new_element
else:
self.head = new_element
def is_empty(self):
"""
判断链表是否为空
"""
return not self.head
def get_length(self):
"""
获取链表的长度
"""
# 临时变量指向队列头部
temp = self.head
# 计算链表的长度变量
length = 0
while temp != None:
length = length+1
temp = temp.next
# 返回链表的长度
return length
def insert(self, position, new_element):
"""
在链表中指定索引处插入元素
"""
if position < 0 or position > self.get_length():
raise IndexError('insert 插入时,key 的值超出了范围')
temp = self.head
if position == 0:
# new_element.next = temp
# self.head = new_element
new_element.next, self.head = temp, new_element
return
i = 0
# 遍历找到索引值为 position 的结点后, 在其后面插入结点
while i < position:
# pre = temp
# temp = temp.next
pre, temp = temp, temp.next
i += 1
# pre.next = node
# node.next = temp
pre.next, new_element.next = new_element, temp
def print_list(self):
"""
遍历链表,并将元素依次打印出来
"""
print("linked_list:")
temp = self.head
new_list = []
while temp is not None:
new_list.append(temp.data)
temp = temp.next
print(new_list)
def remove(self, position):
"""
删除指定索引的链表元素
"""
if position < 0 or position > self.get_length()-1:
# print("insert error")
raise IndexError('删除元素的位置超出范围')
i = 0
temp = self.head
# 遍历找到索引值为 position 的结点
while temp != None:
if position == 0:
self.head = temp.next
temp.next = None
return True
# pre = temp
# temp = temp.next
pre, temp = temp, temp.next
i += 1
if i == position:
# pre.next = temp.next
# temp.next = None
pre.next, temp.next = temp.next, None
return
def reverse(self):
"""
将链表反转
"""
prev = None
current = self.head
while current:
# next_node = current.next
# current.next = prev
# prev = current
# current = next_node
next_node, current.next = current.next, prev
prev, current = current, next_node
self.head = prev
def initlist(self, data_list):
“”“
将列表转换为链表
”“”
# 创建头结点
self.head = Node(data_list[0])
temp = self.head
# 逐个为 data 内的数据创建结点, 建立链表
for i in data_list[1:]:
node = Node(i)
temp.next = node
temp = temp.next
双链表
双向链表(Double_linked_list)也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。
class Node(object):
# 双向链表节点
def __init__(self, item):
self.item = item
self.next = None
self.prev = None
class DLinkList(object):
# 双向链表
def __init__(self):
self._head = None
def is_empty(self):
# 判断链表是否为空
return self._head == None
def get_length(self):
# 返回链表的长度
cur = self._head
count = 0
while cur != None:
count = count+1
cur = cur.next
return count
def travel(self):
# 遍历链表
cur = self._head
while cur != None:
print(cur.item)
cur = cur.next
print("")
def add(self, item):
# 头部插入元素
node = Node(item)
if self.is_empty():
# 如果是空链表,将 node 赋值给 _head
self._head = node
else:
# 将 node 的 next 属性指向头节点 _head
node.next = self._head
# 将头节点 _head 的 prev 属性指向 node
self._head.prev = node
# 将 node 赋值给 _head
self._head = node
def append(self, item):
# 尾部插入元素
node = Node(item)
if self.is_empty():
# 如果是空链表,将 node 赋值给 _head
self._head = node
else:
# 循环移动到链表尾部结点的位置
cur = self._head
while cur.next != None:
cur = cur.next
# 将尾结点 cur 的 next 属性指向 node
cur.next = node
# 将 node 的 prev 属性指向 cur
node.prev = cur
def search(self, item):
# 查找元素是否存在
cur = self._head
while cur != None:
if cur.item == item:
return True
cur = cur.next
return False
def insert(self, pos, item):
# 在指定位置添加节点
if pos <= 0:
self.add(item)
elif pos > (self.length()-1):
self.append(item)
else:
node = Node(item)
cur = self._head
count = 0
# 移动到指定位置的前一个位置
while count < (pos-1):
count += 1
cur = cur.next
# 将 node 的 prev 属性指向 cur
node.prev = cur
# 将 node 的 next 属性指向 cur 的下一个节点
node.next = cur.next
# 将 cur 的下一个节点的 prev 属性指向 node
cur.next.prev = node
# 将 cur 的 next 指向 node
cur.next = node
def remove(self, item):
# 删除元素
if self.is_empty():
return
else:
cur = self._head
if cur.item == item:
# 如果首节点的元素即是要删除的元素
if cur.next == None:
# 如果链表只有这一个节点
self._head = None
else:
# 将第二个节点的 prev 属性设置为 None
cur.next.prev = None
# 将 _head 指向第二个节点
self._head = cur.next
return
while cur != None:
if cur.item == item:
# 将 cur 的前一个节点的 next 指向 cur 的后一个节点
cur.prev.next = cur.next
# 将 cur 的后一个节点的 prev 指向 cur 的前一个节点
cur.next.prev = cur.prev
break
cur = cur.next
队列
队列 (queue) 是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
class Node(object):
def __init__(self, elem, next=None):
self.elem = elem # 表示对应的元素值
self.next = next # 表示下一个链接的链点
class Queue(object):
def __init__(self):
self.head = None # 头部链点为 None
self.rear = None # 尾部链点为 None
def is_empty(self):
return self.head is None # 判断队列是否为空
def enqueue(self, elem):
p = Node(elem) # 初始化一个新的点
if self.is_empty():
self.head = p # 队列头部为新的链点
self.rear = p # 队列尾部为新的链点
else:
self.rear.next = p # 队列尾部的后继是这个新的点
self.rear = p # 然后让队列尾部指针指向这个新的点
def dequeue(self):
if self.is_empty(): # 判断队列是否为空
print('Queue_is_empty') # 若队列为空,则退出 dequeue 操作
else:
result = self.head.elem # result为队列头部元素
self.head = self.head.next # 改变队列头部指针位置
return result # 返回队列头部元素
def peek(self):
if self.is_empty(): # 判断队列是否为空
print('NOT_FOUND') # 为空则返回 NOT_FOUND
else:
return self.head.elem # 返回队列头部元素
def print_queue(self):
print("queue:")
temp = self.head
myqueue = [] # 暂时存放队列数据
while temp is not None:
myqueue.append(temp.elem)
temp = temp.next
print(myqueue)