Python数据结构与算法——数据结构(栈、队列)

目录

数据结构介绍

列表

栈的基本操作:

栈的实现(使用一般列表结构即可实现):

栈的应用——括号匹配问题

队列

队列的实现方式——环形队列

 队列的实现方式——双向队列

 队列内置模块

栈和队列应用——迷宫问题

栈——深度优先搜索

 队列——广度优先搜索


数据结构介绍

介绍:

  • 数据结构是值相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成。
  • 简单说:数据结构就是设计数据以何种方式组织并存储在计算机中。
  • 比如:列表、集合与字典等都是一种数据结构。
  • 程序 = 数据结构 + 算法

分类:

  • 数据结构按照其逻辑结构可分为线性结构、树结构、图结构。
    • 线性结构:数据结构中存在一对一的相互关系
    • 树结构:数据结构中存在一对多的相互关系
    • 图结构:数据结构中存在多对多的相互关系

列表

        列表与其他编程语言的数组有区别:1、数组元素类型相同;2、数组长度固定。

列表:是一种基本数据类型。

操作:

  • 查找:O(1)
  • 插入:O(n)
  • 删除:O(n)

  • 栈:是一个数据集合,可以理解为只能在一端进行插入或者删除操作的列表。
  • 特点:后进先出LIFO
  • 概念:栈顶、栈底

栈的基本操作:

  • 进栈(压栈):push
  • 出栈:pop
  • 取栈顶:gettop

栈的实现(使用一般列表结构即可实现):

  • 进栈:li.append
  • 出栈:li.pop
  • 取栈顶:li[-1]

class Stack:def __init__(self):self.stack = []# 进栈def push(self, element):self.stack.append(element)# 出栈def pop(self):return self.stack.pop()# 取栈顶def get_top(self):if len(self.stack) > 0:return self.stack[-1]else:return None# 举例
stack = Stack()
stack.push(1)
stack.push(2)
stack.push(3)
print(stack.pop())

栈的应用——括号匹配问题

        给一个字符串,其中包含小括号、中括号、大括号,求该字符串中的括号是否匹配。

        例如:()()[]{} 匹配、([{()}]) 匹配、[]( 不匹配、[(]) 不匹配

class Stack:def __init__(self):self.stack = []# 进栈def push(self, element):self.stack.append(element)# 出栈def pop(self):return self.stack.pop()# 取栈顶def get_top(self):if len(self.stack) > 0:return self.stack[-1]else:return None# 判断栈是否为空def is_empty(self):return len(self.stack) == 0def brace_match(s):stack = Stack()match = {'}':'{', ']':'[', ')':'('}for ch in s:if ch in {'(', '[', '{'}:stack.push(ch)else:if stack.is_empty():return Falseelif stack.get_top() == match[ch]:stack.pop()else:  # stack.get_top() != match[ch]return Falseif stack.is_empty():return Trueelse:return Falseprint(brace_match("{(){}}{{}{}}"))

队列

  • 队列:队列是一个数据集合,仅允许在列表一端进行插入,另一端进行删除。
  • 进行插入的一端称为队尾(rear),插入动作称为进队或入队。
  • 进行删除的一端称为队头(front),删除动作称为出队。
  • 队列的性质:先进先出FIFO

队列的实现方式——环形队列

环形队列:当队尾指针front = Maxsize - 1时,再前进一个位置就自动到0

  •         队首指针前进1:front = (front + 1) % MaxSize
  •         队尾指针前进1:rear = (rear + 1) % MaxSize
  •         队空条件:rear == front
  •         队满条件:(rear + 1) % MaxSize == front
class Queue:def __init__(self, size = 100):  # 固定队列的长度(做环形队列)self.queue = [0 for _ in range(size)]self.size = sizeself.rear = 0  # 队尾指针(入队)self.front = 0  # 队首指针(出队)# 入队def push(self, element):if not self.is_filled():self.rear = (self.rear + 1) % self.sizeself.queue[self.rear] = elementelse:raise IndexError("Queue is filled.")  # 抛出错误,队满# 出队def pop(self):if not self.is_empty():self.front = (self.front + 1) % self.sizereturn 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.frontq = Queue(6)
for i in range(5):q.push(i)
print(q.is_filled())
print(q.pop())
q.push(4)

 队列的实现方式——双向队列

双向队列:两端都支持进队和出队操作

双向队列基本操作:

  •         队首进队
  •         队首出队
  •         队尾进队
  •         队尾出队

 队列内置模块

使用方法:from collections impport deque

        创建队列:queue = deque()

        进队:append()

        出队:popleft()

        双向队列队首进队:appendleft()

        双向队列队尾出队:pop()

# 双向队列
from collections import deque# 创建队列
q = deque([1, 2, 3, 4, 5], 5)  # 里面的第一个参数为列表,为队列初始化;第二个参数为int,是队列的长度
# 当队列满了之后继续入队,队首位置会向后一位,q.append(1)  # 队尾入队
q.popleft()  # 队首出队# 用于双向队列
q.appendleft()  # 队首入队
q.pop()  # 队尾出队

栈和队列应用——迷宫问题

问题介绍:给一个二维列表,表示迷宫(0表示通道,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, 1, 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]
]# 封装一个列表,表示以什么顺序来探路
dirs = [lambda x,y:(x-1, y),lambda x,y:(x+1, y),lambda x,y:(x, y+1),lambda x,y:(x, y-1),
]def maze_path(x1, y1, x2, y2):  # (x1, y1)起点,(x2, y2)终点stack = []  # 建立栈stack.append((x1, y1))  # 先将起点压入栈while(len(stack)>0):  # 栈不空就循环,如果回溯到起点之后就代表没有路curNode = stack[-1]  # 当前位置if curNode[0] == x2 and curNode[1] == y2:  # 判断当前点是否为终点# 走到终点for p in stack:print(p)return True# 上下左右四个方向搜索:上(x-1, y), 下(x+1, y), 左(x, y+1), 右(x, y-1)for dir in dirs:nextNode = dir(curNode[0], curNode[1])# 如果下一个节点可以走if maze[nextNode[0]][nextNode[1]] == 0:stack.append(nextNode)  # 如果可以走,就将该点压入栈maze[nextNode[0]][nextNode[1]] = 2  # 然后将该点标记成2,2表示路以及走过break  # 找到一个就break,往下走else:  # 找不到就回退maze[nextNode[0]][nextNode[1]] = 2stack.pop()  # 回退else:  # 栈空,未找到路print("没有路")return Falsemaze_path(1, 1, 8, 8)

 队列——广度优先搜索

        可以计算最短路径

  • 思路:从一个节点开始,寻找所有接下来能继续走的点,继续不断寻找,直到找到出口。
  • 使用队列存储当前正在考虑的节点,使用列表存储走过的路以及其上个节点下标。
from collections import dequemaze = [[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, 1, 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],
]# 封装一个列表,表示上下左右四个坐标
dirs = [lambda x, y: (x + 1, y),lambda x, y: (x - 1, y),lambda x, y: (x, y - 1),lambda x, y: (x, y + 1),
]# 用于输出路径
def print_r(path):curNode = path[-1]realpath = []while curNode[2] != -1:realpath.append(curNode[0:2])curNode = path[curNode[2]]realpath.append(curNode[0:2])  # 最后将起点放进去realpath.reverse()for node in realpath:print(node)# 广度优先搜索
def maze_path_queue(x1, y1, x2, y2):queue = deque()  # 创建队列queue.append((x1, y1, -1))  # 先将起点存储path = []while len(queue) > 0:  # 队空表示无路curNode = queue.pop()path.append(curNode)if curNode[0] == x2 and curNode[1] == y2:# 终点print_r(path)return Truefor dir in dirs:nextNode = dir(curNode[0], curNode[1])if maze[nextNode[0]][nextNode[1]] == 0:queue.append((nextNode[0], nextNode[1], len(path)-1))  # 后续节点进队,记录从哪个节点过来maze[nextNode[0]][nextNode[1]] = 2  # 标记为已经走过else:print("没有路")return Falsemaze_path_queue(1, 1, 8, 8)

代码自己手动敲一遍理解更深哦!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/787085.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

25.死锁

一个线程如果需要同时获取多把锁,就容易产生死锁。 t1线程获得A对象锁,接下来想获取B对象的锁。 t2线程获得B对象锁,接下来想获取A对象的锁。 /*** 死锁demo* param args*/public static void main(String[] args) {Object a new Object(…

RabbitMQ的部分模式

1发布订阅模式 发送者 package org.example; import com.alibaba.fastjson.JSON; import com.rabbitmq.client.BuiltinExchangeType; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; import ja…

如何使用【知乎引流软件工具】进行有效引流

知乎,这个内容平台,无疑是品牌和创作者们的乐园。 品牌能在这里找到目标关键词,而创作者们的内容则可以吸引流量,助力各种项目。 别被那些所谓的爆粉秘籍迷惑了,真正的成功往往来自于扎实的内容和策略,而非…

云原生(七)、Kubernetes初学 + 裸机搭建k8s集群

Kubernetes简介 Kubernetes(通常简称为K8s)是一个开源的容器编排平台,最初由Google设计和开发,现在由Cloud Native Computing Foundation(CNCF)维护。它旨在简化容器化应用程序的部署、扩展和管理。 Kube…

IPC 进程间通信

IPC InterProcess Communication The concept of IPC Each process has a differnt user addess space,and local variables 各自看不见,so 进程间通信 need kernel(内核), so a buffer is opened in the kernel,process 1 copies data from user space to this buffer,and …

Linux:运营商在网络中扮演的角色

文章目录 ip目前的问题ip目前的几种解决方案私有ipVS公有ip运营商再谈ip划分运营商的角度看ip 本篇总结的是运营商在网络中扮演的角色 ip目前的问题 在目前看来,ip最大的问题是ip号不够用了,那这个问题如何解决呢? 在之前的内容中有子网掩…

朗之万方程,机器学习与液体中的粒子运动

目录 一、说明二、朗之万方程的诞生2.1 牛顿力学2.2 流体中的随机运动 三、小质量物体布朗运动方程四、布朗运动的Python代码五、稳定性讨论5.1 波尔兹曼分布5.2 梯度下降算法 六、随机梯度下降(SGD)和小批量梯度下降七、机器学习与物理,作为…

加密软件VMProtect教程:使用脚本-功能

VMProtect是新一代软件保护实用程序。VMProtect支持德尔菲、Borland C Builder、Visual C/C、Visual Basic(本机)、Virtual Pascal和XCode编译器。 同时,VMProtect有一个内置的反汇编程序,可以与Windows和Mac OS X可执行文件一起…

最大连续1的个数||

又用到滑动窗口&#xff0c;关键在于要维持窗口内0的数量在k内 #include<stdio.h> #include<string.h>int Max(int a,int b){return (a>b)?a:b; }int findMaxConsecutiveOnes(int* nums,int numsSize,int k){int left 0;int right 0;int flag 0;//记录包含…

系统设计理念:满足设计要求

在今天的文章中,我们将层层剥离并深入探讨系统设计要求的本质。 让我们了解系统设计的支柱以及如何创建强大且有弹性的应用程序。 什么是好的设计? 在我们深入讨论技术细节之前,让我们先讨论一下什么是好的设计。 当我们谈论系统架构中的良好设计时,我们关注几个关键原则:…

初始C语言最后一章《编译、链接与预处理详解》

前言 感谢老铁们的陪伴和支持&#xff0c;初始C语言专栏在本章内容也是要结束了&#xff0c;这创作一路下来也是很不容易&#xff0c;如果大家对 Java 后端开发感兴趣&#xff0c;欢迎各位老铁来我的Java专栏&#xff01;当然了&#xff0c;我也会更新几章C语言实现简单的数据结…

C++中的面向对象到底是什么

C中的面向对象到底是什么 对象嘛&#xff0c;就和大家都有的对象一样&#xff0c;两只眼睛、一个嘴巴、两条腿…… 对不起跑题了&#xff0c;C的面向对象中的对象可不是显示中的对象哦&#xff0c;但是有一些相似之处&#xff0c;有对象的同学可以参考着去学习C面向对象的概念…

HackTheBox-Machines--Builder

文章目录 1 端口扫描2 测试思路3 漏洞测试 Builder测试过程 1 端口扫描 nmap -sC -sV 10.129.230.2202 测试思路 系统开启了22和8080端口&#xff0c;22端口无账号密码&#xff0c;测试方向主要从8080的jenkins服务开始测试。 在测试开源系统时&#xff0c;可以下载源代码或本地…

基于springboot的一站式家装服务管理系统

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于springboot的一站式家装服务管理系统…

766. 托普利茨矩阵

给你一个 m x n 的矩阵 matrix 。如果这个矩阵是托普利茨矩阵&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 如果矩阵上每一条由左上到右下的对角线上的元素都相同&#xff0c;那么这个矩阵是 托普利茨矩阵 。 示例 1&#xff1a; 输入&#xff1a;matr…

3、jvm基础知识(三)

如何判断堆上的对象没有被引用&#xff1f; 常见的有两种判断方法&#xff1a;引用计数法和可达性分析法。 引用计数法会为每个对象维护一个引用计数器&#xff0c;当对象被引用时加1&#xff0c;取消引用时减1。 引用计数法的优点是实现简单&#xff0c;缺点有两点&#xff1…

电机选型与直线模组(简化版)

2-1电机分类和普通电机选型 1、电机及其原理的基本认知&#xff1a; 电动机我们平时简称电机&#xff0c;大部分情况下指的都是通电后&#xff0c;输出轴会旋转运动的设备。即将电能转换为机械能&#xff0c;供我们使用以驱动机构运行。电机简单的讲&#xff0c;其实就是一个…

ubuntu 一键安装python3.10和pip3.10

在Ubuntu系统上&#xff0c;您可以通过添加官方Python PPA来安装Python 3.10。以下是通过命令行安装Python 3.10和pip的步骤&#xff1a; 打开终端。 添加deadsnakes PPA&#xff08;Personal Package Archive&#xff09;&#xff1a; sudo add-apt-repository ppa:deadsna…

梨花带雨网页音乐播放器二开优化修复美化版全开源版本源码

源码简介 最新梨花带雨网页音乐播放器二开优化修复美化版全开源版本源码下载 梨花带雨播放器基于thinkphp6开发的XPlayerHTML5网页播放器前台控制面板,支持多音乐平台音乐解析。二开内容&#xff1a;修复播放器接口问题&#xff0c;把接口本地化&#xff0c;但是集成外链播放器…

【前端推荐】node.js有哪些命令

Node.js是一个基于Chrome V8引擎的JavaScript运行环境&#xff0c;它允许开发者在服务器端运行JavaScript代码。Node.js拥有丰富的模块和工具&#xff0c;通过命令行工具&#xff0c;可以执行各种任务来简化开发流程。以下是一些常用的Node.js命令&#xff1a; 1. node 这是最…