图的遍历(保留1)

问题描述:

/*    
01.  
02.  
03.*Copyright(c) 2015,烟台大学计算机学院    
04.*All rights reserved.    
05.*文件名称: 111.cpp    
06.*作    者: 田**    
07.*完成日期:2015年11月16日    
08.*版 本 号:V1.0    
09.*    
10.*问题描述:图的遍历
11.*程序输出:    
*/   

函数介绍:

头文件:

#ifndef GRAPH_H_INCLUDED
#define GRAPH_H_INCLUDED

#define MAXV 100                //最大顶点个数
#define INF 32767       //INF表示∞
typedef int InfoType;

//以下定义邻接矩阵类型
typedef struct
{
    int no;                     //顶点编号
    InfoType info;              //顶点其他信息,在此存放带权图权值
} VertexType;                   //顶点类型

typedef struct                  //图的定义
{
    int edges[MAXV][MAXV];      //邻接矩阵
    int n,e;                    //顶点数,弧数
    VertexType vexs[MAXV];      //存放顶点信息
} MGraph;                       //图的邻接矩阵类型

//以下定义邻接表类型
typedef struct ANode            //弧的结点结构类型
{
    int adjvex;                 //该弧的终点位置
    struct ANode *nextarc;      //指向下一条弧的指针
    InfoType info;              //该弧的相关信息,这里用于存放权值
} ArcNode;

typedef int Vertex;

typedef struct Vnode            //邻接表头结点的类型
{
    Vertex data;                //顶点信息
    int count;                  //存放顶点入度,只在拓扑排序中用
    ArcNode *firstarc;          //指向第一条弧
} VNode;

typedef VNode AdjList[MAXV];    //AdjList是邻接表类型

typedef struct
{
    AdjList adjlist;            //邻接表
    int n,e;                    //图中顶点数n和边数e
} ALGraph;                      //图的邻接表类型

//功能:由一个反映图中顶点邻接关系的二维数组,构造出用邻接矩阵存储的图
//参数:Arr - 数组名,由于形式参数为二维数组时必须给出每行的元素个数,在此将参数Arr声明为一维数组名(指向int的指针)
//      n - 矩阵的阶数
//      g - 要构造出来的邻接矩阵数据结构
void ArrayToMat(int *Arr, int n, MGraph &g); //用普通数组构造图的邻接矩阵
void ArrayToList(int *Arr, int n, ALGraph *&); //用普通数组构造图的邻接表
void MatToList(MGraph g,ALGraph *&G);//将邻接矩阵g转换成邻接表G
void ListToMat(ALGraph *G,MGraph &g);//将邻接表G转换成邻接矩阵g
void DispMat(MGraph g);//输出邻接矩阵g
void DispAdj(ALGraph *G);//输出邻接表G

#endif // GRAPH_H_INCLUDED


主函数:

#include <stdio.h>
#include <malloc.h>
#include "graph.h"

void BFS(ALGraph *G, int v)
{
    ArcNode *p;
    int w,i;
    int queue[MAXV],front=0,rear=0; //定义循环队列
    int visited[MAXV];     //定义存放节点的访问标志的数组
    for (i=0; i<G->n; i++) visited[i]=0; //访问标志数组初始化
    printf("%2d",v);            //输出被访问顶点的编号
    visited[v]=1;                       //置已访问标记
    rear=(rear+1)%MAXV;
    queue[rear]=v;              //v进队
    while (front!=rear)         //若队列不空时循环
    {
        front=(front+1)%MAXV;
        w=queue[front];             //出队并赋给w
        p=G->adjlist[w].firstarc;   //找w的第一个的邻接点
        while (p!=NULL)
        {
            if (visited[p->adjvex]==0)
            {
                printf("%2d",p->adjvex); //访问之
                visited[p->adjvex]=1;
                rear=(rear+1)%MAXV; //该顶点进队
                queue[rear]=p->adjvex;
            }
            p=p->nextarc;       //找下一个邻接顶点
        }
    }
    printf("\n");
}


int main()
{
    ALGraph *G;
    int A[5][5]=
    {
        {0,1,0,1,0},
        {1,0,1,0,0},
        {0,1,0,1,1},
        {1,0,1,0,1},
        {0,0,1,1,0}
    };
    ArrayToList(A[0], 5, G);

    printf(" 由2开始广度遍历:");
    BFS(G, 2);

    printf(" 由0开始广度遍历:");
    BFS(G, 0);
    return 0;
}


测试用图:




<think>嗯,用户之前问过如何在C++中实现“按回车退出”的功能,现在又问怎么遍历目录中的所有片。看起来他们可能是在做一个像处理的程序,需要处理多个片文件。比如可能是批量处理片,或者做一个片查看器之类的应用。 首先,我需要确认用户的需求。遍历目录中的片通常涉及到文件系统的操作,但C++标准库在这方面支持有限,可能需要用到第三方库,比如Boost或者C++17的文件系统库。用户可能对不同的方法感兴趣,或者他们正在使用特定的库,比如OpenCV,可能需要结合这些库的功能来实现。 接下来,用户可能关心不同平台(Windows、Linux、macOS)的兼容性问题。比如,文件路径的分隔符在Windows是反斜杠,而其他系统是正斜杠,如何处理。还有,如何递归遍历子目录,或者只处理当前目录下的文件。这些都是需要考虑的点。 然后,关于片格式的判断,用户可能需要检查文件扩展名,比如.jpg、.png等,或者更准确的方法,比如读取文件头。不过检查扩展名比较简单,但可能不够可靠;读取文件头更准确,但实现起来复杂一些。需要根据用户的需求来推荐合适的方法。 另外,用户可能希望得到具体的代码示例,比如使用C++17的filesystem库,或者Boost,或者结合OpenCV来读取片。之前的回答中提到了OpenCV,所以可能用户已经在使用OpenCV处理像,因此结合OpenCV的代码会更相关。 还要注意代码的健壮性,比如处理权限问题,文件是否可读,避免程序崩溃。可能需要添加错误处理机制,比如try-catch块,或者检查文件是否能被正确打开。 用户可能没有提到递归遍历,但可能需要这个功能,所以应该提到是否包含子目录,并给出相应的示例。比如,使用递归函数或者filesystem的递归目录迭代器。 还有,如何将文件路径传递给OpenCV的imread函数,可能需要将路径转换为字符串,并处理不同平台的路径分隔符问题,比如使用generic_string()方法。 最后,可能需要给出一些扩展建议,比如多线程处理大量片,或者性能优化,处理大文件时的内存管理,或者异常处理的具体例子。 总结下来,回答需要涵盖不同方法(C++17、Boost、OpenCV),处理不同平台,检查片格式的方法,代码示例,错误处理,以及可能的扩展建议。这样用户可以根据自己的环境和需求选择合适的解决方案。</think>在 C++ 中遍历目录中的所有片文件,可通过以下方法实现。这里提供 **跨平台** 的两种主流方案,并附带 OpenCV 读取片的集成示例: --- ### 方法一:C++17 标准文件系统库(推荐) 需包含头文件 `<filesystem>`,并启用 C++17 编译标准(编译时添加 `-std=c++17`)。 ```cpp #include <iostream> #include <filesystem> #include <vector> #include <opencv2/opencv.hpp> namespace fs = std::filesystem; // 判断是否为片文件(通过扩展名) bool isImageFile(const fs::path& path) { static const std::vector<std::string> imageExtensions = { ".jpg", ".jpeg", ".png", ".bmp", ".tiff", ".webp" }; std::string ext = path.extension().string(); std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower); return std::find(imageExtensions.begin(), imageExtensions.end(), ext) != imageExtensions.end(); } int main() { std::string directory = "./images"; // 目标目录 std::vector<fs::path> imagePaths; // 遍历目录 for (const auto& entry : fs::directory_iterator(directory)) { if (entry.is_regular_file() && isImageFile(entry.path())) { imagePaths.push_back(entry.path()); } } // 用 OpenCV 读取所有片 for (const auto& path : imagePaths) { cv::Mat img = cv::imread(path.generic_string()); if (!img.empty()) { std::cout << "Loaded: " << path << " (Size: " << img.cols << "x" << img.rows << ")\n"; } } return 0; } ``` --- ### 方法二:Boost 文件系统库(兼容旧编译器) 需先安装 [Boost 库](https://www.boost.org/),编译时链接 Boost 文件系统。 ```cpp #include <iostream> #include <vector> #include <boost/filesystem.hpp> #include <opencv2/opencv.hpp> namespace fs = boost::filesystem; // 扩展名判断函数(同方法一) int main() { fs::path directory("./images"); std::vector<fs::path> imagePaths; // 遍历目录 for (fs::directory_iterator it(directory); it != fs::directory_iterator(); ++it) { if (fs::is_regular_file(*it) && isImageFile(it->path())) { imagePaths.push_back(it->path()); } } // OpenCV 读取代码同方法一 } ``` --- ### 关键说明 1. **路径处理** - 使用 `path.generic_string()` 确保路径跨平台兼容(将 `\` 转换为 `/`) - 示例中的 `./images` 可替换为绝对路径(如 `D:/photos`) 2. **扩展名检查优化** - 更严格的方式:通过读取文件头验证片格式(需实现文件头解析) - 简单方式:示例中的扩展名过滤已能满足大部分需求 3. **递归遍历子目录** ```cpp // C++17 for (const auto& entry : fs::recursive_directory_iterator(directory)) // Boost for (fs::recursive_directory_iterator it(directory); it != fs::recursive_directory_iterator(); ++it) ``` 4. **异常处理** 添加 `try-catch` 块处理权限不足或无效路径: ```cpp try { // 遍历代码 } catch (const fs::filesystem_error& ex) { std::cerr << "文件系统错误: " << ex.what() << std::endl; } ``` --- ### 扩展应用:实时处理目录中的新增片 可结合文件监控库(如 `std::filesystem` 的 `directory_entry` 状态检查或第三方库如 `inotify`)实现动态监测目录变化。 --- ### 性能建议 - **多线程处理**:对大量片可使用线程池并行加载 - **延迟加载**:仅在需要时加载片(避免内存爆炸) - **缓存机制**:对重复访问的保留引用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值