蓝桥杯备考——算法

一、排序

冒泡排序、选择排序、插入排序、 快速排序、归并排序、桶排序

 

二、枚举

三、二分查找与二分答案

四、搜索(DFS)

DFS(DFS基础、回溯、剪枝、记忆化)

1.DFS算法(深度优先搜索算法)

深度优先搜索( DFS )是一种用于遍历或搜索图或树的算法,它从起始节点开始,沿着一条路径一直深入直到无法继续为止,然后回溯到上一个节点继续探索。 DFS 使用来记录遍历的路径,它优先访问最近添加到栈的节点。

DFS 的主要优点是简单且易于实现,它不需要额外的数据结构来记录节点的访问情况,仅使用栈来存储遍历路径。然而, DFS 可能会陷入无限循环中,因为它不考虑节点是否已经访问过。

  对于一个连通图,深度优先搜索遍历的过程如下:

(1)从图中某个顶点v出发,访问v;

(2)找到刚访问过的顶点的第一个未被访问的邻接点,访问该顶点。 以该顶点为新顶点,重 复此步骤, 直至刚访问过的顶点没有未被访问的邻接点为止。

(3)返回前一个访问过的且仍有未被访问的邻接点的顶点,找出该顶点的下一个未被访问的邻接点, 访问该顶点。

(4)重复步骤 (2) 和(3), 直至图中所有顶点都被访问过,搜索结束。 

677c768ab5eb8b76c9f1c64d779c35b6.png

顶点访问序列:v1 -> v2 -> v4 -> v8 -> v5 -> v3 -> v6 -> v7

DFS 使用来记录遍历的路径,它优先访问最近添加到栈的节点。

 显然, 深度优先搜索遍历连通图是一个递归的过程。 为了在遍历过程中便千区分顶点是否已

 被访问,需附设访问标志数组 visited[n] , 其初值为 "false", 一旦某个顶点被访问,则其相应的分

量置为 "true"。  

python语言:

# 图的DFS遍历
def dfs(graph, start, visited):
    # 访问当前节点
    print(start, end=' ')
    # 标记当前节点为已访问
    visited[start] = True
    # 遍历当前节点的邻居节点
    for neighbor in graph[start]:
        # 如果邻居节点未被访问,则继续深度优先搜索
        if not visited[neighbor]:
            dfs(graph, neighbor, visited)

# 图的邻接表表示
graph = {
    '1': ['2', '3'],
    '2': ['2', '4', '5'],
    '3': ['1', '6', '7'],
    '4': ['2','8'],
    '5': ['2','8'],
    '6': ['3','7'],
    '7': ['3','6'],
    '8': ['4','5']
}

# 标记节点是否已访问的列表
visited = {node: False for node in graph}

# 从节点A开始进行DFS遍历
print("DFS遍历结果:")
dfs(graph, '1', visited)

C++ / C语言:

算法1.深度优先搜索遍历连通图

// 1. 深度优先搜索遍历连通图
bool visited[MVNum];         // 访问标志数组,其初值设为“false”
void DFS(Graph G, int v)
{    // 从第v个顶点出发 递归地深度优先遍历图G
    cout << v; visited[v] = true;
    for (w=FirstAdjVex(G,v); w>=0; w=NextAdjVex(G,v,w))
        // 依次检查v的所有邻接点w,FirstAdjVex(G,v)表示v的第一个邻接点
        // NextAdjVex(G,v,w)表示v相对于w的下一个邻接点,w>=0表示存在邻接点
        if (!visited[w])    DFS(G,w);      // 对v的尚未访问的邻接点w递归调用DFS
}

算法2.深度优先搜索遍历 非连通图

若是非连通图, 上述遍历过程执行之后, 图中一定还有顶点未被访间,需要从图中另选

一个未被访问的顶点作为起始点 , 重复上述深度优先搜索过程, 直到图中所有顶点均被访问

过为止。这样, 要实现对非连通图的遍历,需要循环调用算法 1, 具体实现如算法 2所示。

void DFSTraverse(Graph G) 
{ //对非连通图G做深度优先遍历
    for(v=O;v<G.vexnum;++v)    visited[v]=false;    // 访问标志数组初始化
    for(v=O;v<G.vexnum;++v)     // 循环调用算法1
        if(!visited[v])    DFS(G,v);     // 对尚未访问的顶点调用DFS
}

算法 3  采用 邻接矩阵 表示图的深度优先搜索遍历

void DFS_AM(AMGraph G,int v) 
{    // 图G为 邻接矩阵类型,从第v个顶点出发深度优先搜索遍历图G
    cout<<v; visited[v]=true;     // 访问第v个顶点,并置访问标志数组相应分址值为true
    for(w=O; w<G.vexnum; w++)     // 依次检查邻接矩阵 v所在的行
        if((G.arcs[v][w] !=O) && (!visited[w]))    DFS(G,w);  //G.arcs[v][w] ! =0表示w是v的邻接点, 如果w未访问, 则递归调用DFS
}

算法 4 采用邻接表表示图的深度优先搜索遍历

void DFS_AL (ALGraph G,int v) 
{    //图G为 邻接表 类型, 从第v个顶点出发深度优先搜索遍历图G
    cout<<v; visited[v]=true;  // 访问第v个顶点,并置访问标志数组相应分量值为true
    p=G.vertices[v] .firstarc;   //p指向v的边链表的第一个边结点
    while(p!=NULL)     // 边结点非空
    {
        w=p->adjvex;           // 表示w是v的邻接点
        if(!visited[w])    DFS(G,w);    // 如果w未访问, 则递归调用DFS
        p=p->nextarc;         //p指向下一个边结点
    }
}



例题:1.最大连通

问题描述:(填空题)

小兰有一个30行60列的数字矩阵,矩阵中的每个数都是0或1。


110010000011111110101001001001101010111011011011101001111110

010000000001010001101100000010010110001111100010101100011110 

001011101000100011111111111010000010010101010111001000010100 

101100001101011101101011011001000110111111010000000110110000 

010101100100010000111000100111100110001110111101010011001011 

010011011010011110111101111001001001010111110001101000100011 

101001011000110100001101011000000110110110100100110111101011 

101111000000101000111001100010110000100110001001000101011001 

001110111010001011110000001111100001010101001110011010101110 

001010101000110001011111001010111111100110000011011111101010 

011111100011001110100101001011110011000101011000100111001011 

011010001101011110011011111010111110010100101000110111010110 

001110000111100100101110001011101010001100010111110111011011 

111100001000001100010110101100111001001111100100110000001101 

001110010000000111011110000011000010101000111000000110101101 

100100011101011111001101001010011111110010111101000010000111 

110010100110101100001101111101010011000110101100000110001010 

110101101100001110000100010001001010100010110100100001000011 

100100000100001101010101001101000101101000000101111110001010 

101101011010101000111110110000110100000010011111111100110010 

101111000100000100011000010001011111001010010001010110001010 

001010001110101010000100010011101001010101101101010111100101 

001111110000101100010111111100000100101010000001011101100001 

101011110010000010010110000100001010011111100011011000110010 

011110010100011101100101111101000001011100001011010001110011 

000101000101000010010010110111000010101111001101100110011100 

100011100110011111000110011001111100001110110111001001000111 

111011000110001000110111011001011110010010010110101000011111 

011110011110110110011011001011010000100100101010110000010011 

010011110011100101010101111010001001001111101111101110011101

 如果从一个标为1的位置可以通过上下左右走到另一个标为1的位置,则称两个位置连通。与某一个标为1的位置连通的所有位置(包括自己)组成一个连通分块。

请问矩阵中最大的连通分块有多大?

答案:

import os
import sys


def dfs(x, y, num): # x,y是当前的位置,num是最大连通的数量
    vis[x][y] = 1   # 表明这个位置已经被搜素过了
    for dx,dy in [(1, 0), (-1, 0), (0,1), (0, -1)]:   # 标准的上下左右搜索
        current_x = x + dx
        current_y = y + dy
        if 0 <= current_x < 30 and 0 <= current_y <60:  # 边界限制
            try:
                if vis[current_x][current_y] != 1 and data[current_x][current_y] == '1':  # 上下左右有位置没有被探索同时还是字符串的'1'
                    num = dfs(current_x,current_y,num)
            except:   # 这里是方便找到如果输入错误是在哪,用来检查循环条件是否写错
                print(current_x)
                print(current_y)
    return num + 1    # 本身的1加上所有与它相连的num

data =[
"110010000011111110101001001001101010111011011011101001111110",

"010000000001010001101100000010010110001111100010101100011110",

"001011101000100011111111111010000010010101010111001000010100",

"101100001101011101101011011001000110111111010000000110110000",

"010101100100010000111000100111100110001110111101010011001011",

"010011011010011110111101111001001001010111110001101000100011",

"101001011000110100001101011000000110110110100100110111101011",

"101111000000101000111001100010110000100110001001000101011001",

"001110111010001011110000001111100001010101001110011010101110",

"001010101000110001011111001010111111100110000011011111101010",

"011111100011001110100101001011110011000101011000100111001011",

"011010001101011110011011111010111110010100101000110111010110",

"001110000111100100101110001011101010001100010111110111011011",

"111100001000001100010110101100111001001111100100110000001101",

"001110010000000111011110000011000010101000111000000110101101",

"100100011101011111001101001010011111110010111101000010000111",

"110010100110101100001101111101010011000110101100000110001010",

"110101101100001110000100010001001010100010110100100001000011",

"100100000100001101010101001101000101101000000101111110001010",

"101101011010101000111110110000110100000010011111111100110010",

"101111000100000100011000010001011111001010010001010110001010",

"001010001110101010000100010011101001010101101101010111100101",

"001111110000101100010111111100000100101010000001011101100001",

"101011110010000010010110000100001010011111100011011000110010",

"011110010100011101100101111101000001011100001011010001110011",

"000101000101000010010010110111000010101111001101100110011100",

"100011100110011111000110011001111100001110110111001001000111",

"111011000110001000110111011001011110010010010110101000011111",

"011110011110110110011011001011010000100100101010110000010011",

"010011110011100101010101111010001001001111101111101110011101"]
res = 0
vis = [[0 for i in range(60)] for j in range(30)]   # 标记数组
for i in range(30):  # i和j是位置
    for j in range(60):
        if data[i][j] == '1' and vis[i][j] == 0:
            num = 0
            num = dfs(i,j,num)
            res = max(num, res)
print(res)

例题2.

 

2. 广度优先搜索( BFS )算法

是一种用于遍历或搜索图或树的算法,它从起始节点开始,逐层地向外扩展,先访问当前节点的所有邻居节点,然后再访问邻居节点的邻居节点,直到遍历完所有节点。

BFS 使用队列来记录遍历的路径,它优先访问最早添加到队列的节点。 BFS 的主要优点是能够找到起始节点到目标节点的最短路径,因为它是逐层遍历的。

677c768ab5eb8b76c9f1c64d779c35b6.png

python语言

from collections import deque

# 图的BFS遍历
def bfs(graph, start):
    # 使用队列来记录遍历路径
    queue = deque([start])
    # 标记节点是否已访问的集合
    visited = set([start])

    while queue:     # 当栈不为空
        node = queue.popleft()    # 左端出栈
        print(node, end=' ')

        for neighbor in graph[node]:
            if neighbor not in visited:
                queue.append(neighbor)    # 右端进栈
                visited.add(neighbor)

# 图的邻接表表示
graph = {
    '1': ['2', '3'],
    '2': ['2', '4', '5'],
    '3': ['1', '6', '7'],
    '4': ['2','8'],
    '5': ['2','8'],
    '6': ['3','7'],
    '7': ['3','6'],
    '8': ['4','5']
}

# 从节点A开始进行BFS遍历
print("BFS遍历结果:")
bfs(graph, '1')      # 1 2 3 4 5 6 7 8

python: collections模块——双向队列(deque)
类似于list的容器,可以快速的在队列头部和尾部添加、删除元素

 

3.  DFS 与 BFS 的对比

DFSBFS 是两种不同的图遍历算法,在不同的应用场景下具有不同的优势:

  • DFS 适用于找到起始节点到目标节点的路径,但不一定是最短路径。它通过递归的方式深入探索图的分支,因此对于深度较小的图或树, DFS 通常表现较好。
  • BFS 适用于找到起始节点到目标节点的最短路径。它通过逐层遍历图的节点,从而保证找到的路径是最短的。在需要寻找最短路径的情况下, BFS 是更好的选择

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

‘conda‘ 不是内部或外部命令,也不是可运行的程序或批处理文件,Miniconda

下载了conda&#xff0c;但是在cmd里执行conda --version会显示’conda’ 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。 原因是环境变量里没有添加conda&#xff0c;无法识别路径。 需要在系统环境变量里添加如下路径&#xff1a; 保存之后重新打开cmd&am…

UE5 随机生成地牢关卡

参考视频&#xff1a;【UE5 | 教程 | 地编】虚幻引擎5 中创建史诗级 程序化 地下城_哔哩哔哩_bilibili 首先创建一个父项Actor 这个BOX碰撞提是和地板重叠的 这三个是场景组件&#xff0c;这个ExitsFolder下面的箭头等会会在子蓝图中添加 接下来创建BP_MasterRoom的子蓝图&…

Qt信号和槽-->day04

Qt信号和槽 标准的信号和槽函数Qt中的槽函数Qt中的信号 connect案例 自定义信号和槽案例分析 信号槽的拓展信号连接信号案例 信号槽的两种连接方式Qt5中的处理方式Qt4中的处理方式Qt5处理信号槽重载问题案例 lambda表达式简单案例Qt中的应用 补充知识点 标准的信号和槽函数 QW…

十大经典排序算法-冒泡算法详解介绍

1、十大经典排序算法 排序算法是《数据结构与算法》中最基本的算法之一。 排序算法可以分为内部排序和外部排序&#xff0c;内部排序是数据记录在内存中进行排序&#xff0c;而外部排序是因排序的数据很大&#xff0c;一次不能容纳全部的排序记录&#xff0c;在排序过程中需要…

ASMR助眠声音视频素材去哪找 吃播助眠素材网站分享

在快节奏的现代生活中&#xff0c;越来越多的人感到压力山大&#xff0c;许多人开始寻求助眠和放松的方式。而ASMR&#xff08;自发性知觉经络反应&#xff09;助眠声音视频&#xff0c;凭借其独特的声音刺激和放松效果&#xff0c;成为了睡前的“神器”。如果你是一位内容创作…

【Linux】常用命令(2.6万字汇总)

文章目录 Linux常用命令汇总1. 基础知识1.1. Linux系统命令行的含义1.2. 命令的组成 2. 基础知识2.1. 关闭系统2.2. 关闭重启2.3. 帮助命令&#xff08;help&#xff09;2.4. 命令说明书&#xff08;man&#xff09;2.5. 切换用户&#xff08;su&#xff09;2.6.历史指令 3.目录…

量化分析工具日常操作日记-5-通合科技

使用量化分析微信小程序工具“梦想兔企业智能风险分析助手”日常操作日记-5-军工-通合科技&#xff08;300491&#xff09;。 周末国家新政策&#xff0c;要大力支持军工行业&#xff0c;我用工具挖掘了两个低位股&#xff0c;供大家参考。通合科技&#xff08;300491&#xff…

4D施工奇迹:废弃码头变身地标体育场

SYNCHRO 促进协同和战略性施工&#xff0c;完成大型项目交付 改造举世闻名的海滨城市 为了提升球迷的比赛日体验&#xff0c;英国足球俱乐部埃弗顿足球俱乐部正在利物浦默西河畔废弃的布拉姆利摩尔码头建造一座新的现代化体育场。该体育场是利物浦城市总体规划的一部分&#xf…

图神经网络(GNN)入门笔记(1)——图信号处理与图傅里叶变换

一、信号处理&#xff1a;时域与频域 时域&#xff08;Time Domain&#xff09;是我们生活中常见的信号表示方式&#xff0c;以横轴为时间&#xff0c;纵轴为信号该时刻的强度&#xff08;幅度&#xff09;&#xff0c;就可以得到一张时域图。打个比方&#xff0c;通过每时每刻…

【八百客CRM-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

【AIGC】如何在ChatGPT中制作个性化GPTs应用详解

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | GPTs应用实例 文章目录 &#x1f4af;前言&#x1f4af;什么是GPTsGPTs的工作原理GPTs的优势GPTs的应用前景总结 &#x1f4af;创建GPTS应用的基本流程进入GPTs创建界面方式一&#xff1a;按照引导完成生成创建GPTs方式二…

读书笔记--Java与线程

并发不一定要依赖多线程&#xff08;如PHP中很常见的多线程并发&#xff09;&#xff0c;但是Java里面谈论并发&#xff0c;大多数都与线程脱不了关系。 线程的实现 我们都知道&#xff0c;线程是比进程更轻量级的调度执行单位&#xff0c;线程的引入&#xff0c;可以把一个进程…

PICO+Unity 用手柄点击UI界面

如果UI要跟随头显&#xff0c;可将Canvas放置到XR Origin->Camera Offset->Main Camera下 1.Canvas添加TrackedDeviceGraphicRaycaster组件 2.EventSystem移动默认的Standard Input Module&#xff0c;添加XRUIInputModule组件 3.&#xff08;可选&#xff09;设置射线可…

三十六、Python基础语法(JSON操作)

JSON&#xff08;JavaScript Object Notation&#xff09;是一种基于文本&#xff0c;轻量级的数据交换格式。它易于人阅读和编写&#xff0c;同时也易于机器解析和生成&#xff0c;在自动化测试中经常用来存放测试数据。 JSON的特点&#xff1a; 基于文本&#xff0c;不包含图…

产品设计理念:10个案例分享

在互联网时代&#xff0c;企业通过在线产品为用户提供服务。要在众多竞争产品中脱颖而出并吸引更多用户&#xff0c;企业不仅要提供优质的服务&#xff0c;还要在产品设计上给用户带来卓越的体验。互联网产品设计包括页面布局、服务内容、流程逻辑、色彩搭配、图标、按钮等多个…

智能社区服务小程序+ssm

智能社区服务小程序 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了智能社区服务小程序的开发全过程。通过分析智能社区服务小程序管理的不足&#xff0c;创建了一个计算机管理智能社区服务小程序的方案。文…

Flutter3.22.2中SliverAppBar设置背景色滑动显示颜色错误

在使用Flutter项目开发中&#xff0c;可能会有页面需要滑动收起标题栏的效果&#xff0c;一般都会使用SliverAppBar来实现&#xff0c;当项目的Flutter的SDK版本升级到3.4后&#xff0c;发现使用了SliverAppBar的页面&#xff0c;在滑动过程中&#xff0c;标题栏和状态栏的颜色…

Odoo | 免费开源ERP:汽车及零配件行业信息化解决方案

文 / 开源智造 Odoo亚太金牌服务 概述 围绕汽车行业产业链上下游企业的整体业务主线&#xff0c;提供面向汽车主机厂整车个性化制造解决方案&#xff0c;产业链上下游一体化协同解决方案&#xff0c;数字化精益制造解决方案、全价值链质量管理解决方案&#xff0c;数字化运营解…

目前对于后期的打算

在完成了 Python 基本语法的学习后&#xff0c;我犹如推开了编程世界的一扇大门&#xff0c;初窥门径却也深知前方还有广袤无垠的知识天地等待我去探索。Python 作为一门广泛应用于软件开发、数据分析和人工智能等领域的高级编程语言&#xff0c;在当今数字化时代具有举足轻重的…

React中右击出现自定弹窗

前言 在react中点击右键,完成阻止浏览器的默认行为,完成自定义的悬浮框(Menu菜单). 版本 "react": "^18.2.0", "umijs/route-utils": "^4.0.1", "antd": "^5.18.1", "ant-design/pro-components": &q…