博客
关于我
06_Python算法+数据结构笔记-队列-链表创建/遍历/插入/删除-双链表
阅读量:789 次
发布时间:2019-03-25

本文共 5555 字,大约阅读时间需要 18 分钟。

#51 队列的实现

Queue 类用于实现固定长度的队列,队列在满的时候空一个位置。构造方法中接受大小参数,默认为100,表示队列最大容纳的元素个数。

代码示例:

class Queue:
def __init__(self, size=100):
self.size = size
self.queue = [0] * size
self.rear = 0 # 队尾指针
self.front = 0 # 队首指针
def push(self, element):
if not self.is_filled():
self.rear = (self.rear + 1) % self.size
self.queue[self.rear] = element
else:
raise IndexError("Queue is filled.")
def pop(self):
if not self.is_empty():
self.front = (self.front + 1) % self.size
return self.queue[self.front]
else:
raise IndexError("Queue is empty.")
def is_empty(self):
return self.rear == self.front
def is_filled(self):
return (self.rear + 1) % self.size == self.front
# 创建一个大小为5的队列
q = Queue(5)
# 将前4个元素逐个推入队列(队满时空一个位置)
for i in range(4):
q.push(i)
# 输出队列是否已满
print(q.is_filled()) # 结果为True
# 取出队列第一个元素
print(q.pop()) # 结果为0
# 推入第5个元素(4)
q.push(4)

#52 队列的内置模块

Python standard library 中提供了 collections.deque 模块,用于实现双向队列。双向队列可以在队列的两端进行元素的插入和删除操作,适用于需要同时处理输入和输出的场景。

使用示例:

from collections import deque
q = deque([1, 2, 3, 4, 5], 5)
# 队尾添加元素
q.append(6)
# 队首移除元素
q.popleft()
# 队尾添加元素
q.appendleft(1) # 队首为1
# 队尾移除元素
q.pop()
# 示例函数用于读取文件的最后N行
def tail(n):
with open('test.txt', 'r', encoding='utf-8') as f:
q = deque(f, n)
return q
# 读取并打印文件的最后5行
for line in tail(5):
print(line, end='')

注意事项:

  • deque 是双端队列,支持 O(1) 时间的 appendleftpopleft 操作。
  • 使用 deque 读取文件时,可以通过指定最大长度来控制读取的行数,确保不会读取超出文件行数。

#53 栈和队列的应用:迷宫问题

迷宫问题可以通过栈(深度优先搜索)或队列(广度优先搜索)来解决。以下使用栈来回溯迷宫路径。

代码示例:

def maze_path(x1, y1, x2, y2):
stack = []
stack.append((x1, y1))
directions = [
lambda x, y: (x + 1, y),
lambda x, y: (x - 1, y),
lambda x, y: (x, y - 1),
lambda x, y: (x, y + 1)
]
maze = [
[1,1,1,1,1,1,1,1,1,1],
[1,0,0,1,0,0,0,1,0,1],
[1,0,0,1,0,0,0,1,0,1],
[1,0,0,0,0,1,1,0,0,1],
[1,0,1,1,1,0,0,0,0,1],
[1,0,0,0,1,0,0,0,0,1],
[1,0,1,0,0,0,1,0,0,1],
[1,0,1,1,1,0,1,1,0,1],
[1,1,0,0,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1,1,1]
]
while stack:
current = stack[-1]
if current[0] == x2 and current[1] == y2:
for node in stack:
print(node)
return True
for direction in directions:
next_node = direction(current[0], current[1])
if 0 <= next_node[0] < 10 and 0 <= next_node[1] < 10 and maze[next_node[0]][next_node[1]] == 0:
stack.append(next_node)
maze[next_node[0]][next_node[1]] = 2
break
else:
maze[current[0]][current[1]] = 2
stack.pop()
print("没有路")
return False
maze_path(1, 1, 8, 8)

#54 使用队列进行迷宫问题:实现

可以使用队列配合哈希表来实现广度优先搜索迷宫路径寻找。

代码示例:

from collections import deque
def maze_path_queue(x1, y1, x2, y2):
queue = deque()
queue.append((x1, y1, -1))
path = []
directions = [
(1, 0),
(-1, 0),
(0, -1),
(0, 1)
]
while queue:
current = queue.popleft()
path.append(current)
x, y = current[0], current[1]
if x == x2 and y == y2:
print("找到了路径:")
for node in path:
print(node)
return True
for dx, dy in directions:
nx = x + dx
ny = y + dy
if 0 <= nx < 10 and 0 <= ny < 10 and maze[nx][ny] == 0:
new_node = (nx, ny, len(path) - 1)
queue.append(new_node)
maze[nx][ny] = 2
print("没有路")
return False
maze_path_queue(1, 1, 8, 8)

#57 链表介绍

链表是一种线性数据结构,由节点组成,每个节点包含数据域和指向下一个节点的指针。链表的优点是插入和删除操作的时间复杂度较低,而缺点是随机访问的时间复杂度较高。

节点类定义:

class Node:
def __init__(self, item):
self.item = item
self.next = None

链表创建示例:

class Node:
def __init__(self, item):
self.item = item
self.next = None
def create_linked_list_head(li):
if not li:
return None
head = Node(li[0])
for element in li[1:]:
node = Node(element)
node.next = head
head = node
return head
lk = create_linked_list_head([1, 2, 3])
print(lk.item) # 输出3
print(lk.next.item) # 输出2
print(lk.next.next.item) # 输出1
print(lk.next.next.next.item) # 报错:没有该属性

#59 链表的插入和删除

链表的插入和删除操作通常采用头插法或尾插法。这些操作不需要移动数据,仅通过指针赋值即可完成,时间复杂度为O(1)。

插入示例:

def insert_after_head(p, new_node):
p.next = new_node
new_node.prior = p
def insert_after_tail(t, new_node):
t.next = new_node
new_node.prior = t
def delete_node_by_prior(prior):
p = prior
p_next = p.next
if p_next:
p_next.prior = prior
del p
# 创建链表测试
a = Node(1)
a.next = Node(2)
a.next.next = Node(3)
insert_after_head(a.next, Node(4))
print(a.next.next.item) # 输出4
delete_node_by_prior(a.next.prior)
print(a.next.item) # still 2

#60 双链表

双链表每个节点包含前驱和后驱指针,支持双向遍历。双链表的插入和删除操作比较灵活。

节点类定义:

class Node:
def __init__(self, item=None):
self.item = item
self.prior = None
self.next = None

双链表插入示例:

def insert_after(tail, new_node):
new_node.next = tail.next
new_node.prior = tail
tail.next = new_node
tail = new_node
def delete_node(node):
if node.prior:
node.prior.next = node.next
if node.next:
node.next.prior = node.prior
if node.prior is None and node.next is None:
head = node
del node

常用操作总结:

  • 插入操作:O(1) 时间。
  • 删除操作:O(1) 时间。
  • Random access:O(n) 时间。

以上内容主要介绍了队列、链表及其应用案例,涵盖了基础理论和实际应用示例。

转载地址:http://ictuk.baihongyu.com/

你可能感兴趣的文章
NOIP2014 提高组 Day2——寻找道路
查看>>
NOIp模拟赛二十九
查看>>
Nokia5233手机和我装的几个symbian V5手机软件
查看>>
Non-final field ‘code‘ in enum StateEnum‘
查看>>
none 和 host 网络的适用场景 - 每天5分钟玩转 Docker 容器技术(31)
查看>>
None还可以是函数定义可选参数的一个默认值,设置成默认值时实参在调用该函数时可以不输入与None绑定的元素...
查看>>
NOPI读取Excel
查看>>
NoSQL&MongoDB
查看>>
NoSQL介绍
查看>>
Notepad ++ 安装与配置教程(非常详细)从零基础入门到精通,看完这一篇就够了
查看>>
Notepad++在线和离线安装JSON格式化插件
查看>>
notepad++最详情汇总
查看>>
notepad如何自动对齐_notepad++怎么自动排版
查看>>
Notification 使用详解(很全
查看>>
NotImplementedError: Cannot copy out of meta tensor; no data! Please use torch.nn.Module.to_empty()
查看>>
Now trying to drop the old temporary tablespace, the session hangs.
查看>>
nowcoder—Beauty of Trees
查看>>
np.arange()和np.linspace()绘制logistic回归图像时得到不同的结果?
查看>>
np.power的使用
查看>>
NPM 2FA双重认证的设置方法
查看>>