IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 数据结构 图 -> 正文阅读

[数据结构与算法]数据结构 图

1. DS图遍历–深度优先搜索

题目描述

给出一个图的邻接矩阵,对图进行深度优先搜索,从顶点0开始

注意:图n个顶点编号从0到n-1

代码框架如下:
在这里插入图片描述
在这里插入图片描述

输入

第一行输入t,表示有t个测试实例

第二行输入n,表示第1个图有n个结点

第三行起,每行输入邻接矩阵的一行,以此类推输入n行

第i个结点与其他结点如果相连则为1,无连接则为0,数据之间用空格隔开

以此类推输入下一个示例

输出

每行输出一个图的深度优先搜索结果,结点编号之间用空格隔开

输入样例

2
4
0 0 1 1
0 0 1 1
1 1 0 1
1 1 1 0
5
0 0 0 1 1
0 0 1 0 0
0 1 0 1 1
1 0 1 0 0
1 0 1 0 0

输出样例

0 2 1 3
0 3 2 1 4

参考代码

#include <iostream>
using namespace std;
const int Maxlen = 20;
class Map
{
private:
    bool Visit[Maxlen];
    int Matrix[Maxlen][Maxlen];
    int Vexnum;
    void DFS(int v);

public:
    void SetMatrix(int vnum, int mx[Maxlen][Maxlen]);
    void DFSTraverse();
};
void Map::SetMatrix(int vnum, int mx[Maxlen][Maxlen])
{
    int i, j;
    Vexnum = vnum;
    for (i = 0; i < Maxlen; i++)
        for (j = 0; j < Maxlen; j++)
            Matrix[i][j] = 0;
    for (i = 0; i < Maxlen; i++)
        for (j = 0; j < Maxlen; j++)
            Matrix[i][j] = mx[i][j];
}
void Map::DFSTraverse()
{
    int v;
    for (int i = 0; i < Maxlen; i++)
        Visit[i] = false;
    for (int i = 0; i < Vexnum; i++)
    {
        if (!Visit[i])
            DFS(i);
    }
    cout << endl;
}
void Map::DFS(int v)
{
    int w, i, k;
    Visit[v] = true;
    cout << v << " ";
    int *AdjVex = new int[Vexnum];
    for (i = 0; i < Vexnum; i++)
        AdjVex[i] = -1;
    k = 0;
    for (i = 0; i < Vexnum; i++)
        if (Matrix[v][i])
            AdjVex[k++] = i;
    i = 0;
    for (i = 0; i < k; i++)
    {
        w = AdjVex[i];
        if (!Visit[w])
            DFS(w);
    }
    delete[] AdjVex;
}
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        int n, i, j;
        cin >> n;
        int mx[Maxlen][Maxlen];
        for (i = 0; i < n; i++)
            for (j = 0; j < n; j++)
            {
                cin >> mx[i][j];
            }
        Map m;
        m.SetMatrix(n, mx);
        m.DFSTraverse();
    }
}

2. DS图遍历–广度优先搜索

题目描述

给出一个图的邻接矩阵,对图进行深度优先搜索,从顶点0开始

注意:图n个顶点编号从0到n-1

代码框架如下:

在这里插入图片描述

输入

第一行输入t,表示有t个测试实例

第二行输入n,表示第1个图有n个结点

第三行起,每行输入邻接矩阵的一行,以此类推输入n行

第i个结点与其他结点如果相连则为1,无连接则为0,数据之间用空格隔开

以此类推输入下一个示例

输出

每行输出一个图的广度优先搜索结果,结点编号之间用空格隔开

输入样例

2
4
0 0 1 1
0 0 1 1
1 1 0 1
1 1 1 0
5
0 0 0 1 1
0 0 1 0 0
0 1 0 1 1
1 0 1 0 0
1 0 1 0 0

输出样例

0 2 3 1
0 3 4 2 1

参考代码

#include <iostream>
#include <queue>
using namespace std;
const int Maxlen = 20;
class Map
{
private:
    bool Visit[Maxlen];
    int Matrix[Maxlen][Maxlen];
    int Vexnum;
    void DFS(int v);
    void BFS(int v);

public:
    void SetMatrix(int vnum, int mx[Maxlen][Maxlen]);
    void DFSTraverse();
    void BFSTraverse();
};
void Map::SetMatrix(int vnum, int mx[Maxlen][Maxlen])
{
    int i, j;
    Vexnum = vnum;
    for (i = 0; i < Maxlen; i++)
        for (j = 0; j < Maxlen; j++)
            Matrix[i][j] = 0;
    for (i = 0; i < Maxlen; i++)
        for (j = 0; j < Maxlen; j++)
            Matrix[i][j] = mx[i][j];
}
void Map::DFSTraverse()
{
    int v;
    for (int i = 0; i < Maxlen; i++)
        Visit[i] = false;
    for (int i = 0; i < Vexnum; i++)
    {
        if (!Visit[i])
            DFS(i);
    }
    cout << endl;
}
void Map::DFS(int v)
{
    int w, i, k;
    Visit[v] = true;
    cout << v << " ";
    int *AdjVex = new int[Vexnum];
    for (i = 0; i < Vexnum; i++)
        AdjVex[i] = -1;
    k = 0;
    for (i = 0; i < Vexnum; i++)
        if (Matrix[v][i])
            AdjVex[k++] = i;
    i = 0;
    for (i = 0; i < k; i++)
    {
        w = AdjVex[i];
        if (!Visit[w])
            DFS(w);
    }
    delete[] AdjVex;
}
void Map::BFSTraverse()
{
    BFS(0);
}
void Map::BFS(int v)
{
    int w, u, i, k;
    int *Adjvex = new int[Vexnum];
    queue<int> Q;
    for (i = 0; i < Vexnum; i++)
        Visit[i] = false;
    for (v = 0; v < Vexnum; ++v)
    {
        if (!Visit[v])
        {
            cout << v << " ";
            Visit[v] = true;
            Q.push(v);
            while (!Q.empty())
            {
                u = Q.front();
                Q.pop();
                k = 0;
                for (i = 0; i < Vexnum; i++)
                    if (Matrix[u][i])
                        Adjvex[k++] = i;
                i = 0;
                for (i = 0; i < k; i++)
                {
                    w = Adjvex[i];
                    if(!Visit[w])
                    {
                        Visit[w] = true;
                        cout << w << " ";
                        Q.push(w);
                    }
                }
            }
        }
    }
    cout << endl;
}
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        int n, i, j;
        cin >> n;
        int mx[Maxlen][Maxlen];
        for (i = 0; i < n; i++)
            for (j = 0; j < n; j++)
            {
                cin >> mx[i][j];
            }
        Map m;
        m.SetMatrix(n, mx);
        m.BFSTraverse();
    }
}

3. 图综合练习–构建邻接表

题目描述

已知一有向图,构建该图对应的邻接表。

邻接表包含数组和单链表两种数据结构,其中每个数组元素也是单链表的头结点,数组元素包含两个属性,属性一是顶点编号info,属性二是指针域next指向与它相连的顶点信息。

单链表的每个结点也包含两个属性,属性一是顶点在数组的位置下标,属性二是指针域next指向下一个结点。

输入

第1行输入整数t,表示有t个图

第2行输入n和k,表示该图有n个顶点和k条弧。

第3行输入n个顶点。

第4行起输入k条弧的起点和终点,连续输入k行

以此类推输入下一个图

输出

输出每个图的邻接表,每行输出格式:数组下标 顶点编号-连接顶点下标-…-^,数组下标从0开始。

具体格式请参考样例数据,每行最后加入“^”表示NULL。

输入样例

1
5 7
A B C D E
A B
A D
A E
B D
C B
C E
E D

输出样例

0 A-1-3-4-^
1 B-3-^
2 C-1-4-^
3 D-^
4 E-3-^

参考代码

#include <iostream>
using namespace std;
class Node
{
public:
    int pos;
    Node *next;
    Node() : next(NULL){};
    Node(int t) : pos(t), next(NULL){};
};
class Map
{
public:
    int Vexnum;
    Node *head;
    char *Vex;
    int index(char c)
    {
        for (int i = 0; i < Vexnum; i++)
        {
            if (c == Vex[i])
                return i;
        }
        return -1;
    }
    Map(int n, int k)
    {
        Vexnum = n;
        Vex = new char[Vexnum];
        head = new Node[Vexnum];
        for (int i = 0; i < n; i++)
        {
            cin >> Vex[i];
        }
        for (int i = 0; i < k; i++)
        {
            char c1, c2;
            cin >> c1 >> c2;
            int num1 = index(c1), num2 = index(c2);
            Node *p = &head[num1];
            while (p->next)
                p = p->next;
            Node *p1 = new Node();
            p1->pos = num2;
            p->next = p1;
        }
    }
    ~Map()
    {
        delete[] Vex;
        for (int i = 0; i < Vexnum; i++)
        {
            Node *p = head[i].next;
            while (p)
            {
                Node *p1 = p;
                p = p->next;
                delete p1;
            }
        }
        delete[] head;
    }
    void display()
    {

        for (int i = 0; i < Vexnum; i++)
        {
            cout << i << " " << Vex[i];
            Node *p = head[i].next;
            while (p)
            {
                cout << "-" << p->pos;
                p = p->next;
            }
            cout << "-^" << endl;
        }
    }
};
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        int n, k;
        cin >> n >> k;
        Map m(n, k);
        m.display();
    }
}

4. DS图—图的邻接矩阵存储及度计算

题目描述

假设图用邻接矩阵存储。输入图的顶点信息和边信息,完成邻接矩阵的设置,并计算各顶点的入度、出度和度,并输出图中的孤立点(度为0的顶点)

–程序要求–
若使用C++只能include一个头文件iostream;若使用C语言只能include一个头文件stdio
程序中若include多过一个头文件,不看代码,作0分处理
不允许使用第三方对象或函数实现本题的要求

输入

测试次数T,每组测试数据格式如下:

图类型 顶点数 (D—有向图,U—无向图)

顶点信息

边数

每行一条边(顶点1 顶点2)或弧(弧尾 弧头)信息

输出

每组测试数据输出如下信息(具体输出格式见样例):

图的邻接矩阵

按顶点信息输出各顶点的度(无向图)或各顶点的出度 入度 度(有向图)。孤立点的度信息不输出。

图的孤立点。若没有孤立点,不输出任何信息。

输入样例

2
D 5
V1 V2 V3 V4 V5
7
V1 V2
V1 V4
V2 V3
V3 V1
V3 V5
V4 V3
V4 V5
U 5
A B C D E
5
A B
A C
B D
D C
A D

输出样例

0 1 0 1 0
0 0 1 0 0
1 0 0 0 1
0 0 1 0 1
0 0 0 0 0
V1: 2 1 3
V2: 1 1 2
V3: 2 2 4
V4: 2 1 3
V5: 0 2 2
0 1 1 1 0
1 0 0 1 0
1 0 0 1 0
1 1 1 0 0
0 0 0 0 0
A: 3
B: 2
C: 2
D: 3
E

参考代码

#include <iostream>
using namespace std;
class Node
{
public:
    int in = 0, out = 0, total = 0;
    void inadd()
    {
        in++;
        total++;
    }
    void outadd()
    {
        out++;
        total++;
    }
};
class Map
{
public:
    int Vexnum;
    char type;
    Node *head;
    string *Vex;
    int **Matrix;
    int index(string c)
    {
        for (int i = 0; i < Vexnum; i++)
        {
            if (c == Vex[i])
                return i;
        }
    }
    Map(int n, char t)
    {
        Vexnum = n;
        type = t;
        Vex = new string[Vexnum];
        Matrix = new int *[Vexnum];
        for (int i = 0; i < Vexnum; i++)
            Matrix[i] = new int[Vexnum];

        head = new Node[Vexnum];
        for (int i = 0; i < Vexnum; i++)
        {
            cin >> Vex[i];
        }

        for (int i = 0; i < Vexnum; i++)
            for (int j = 0; j < Vexnum; j++)
            {
                Matrix[i][j] = 0;
            }

        int k;
        cin >> k;
        while (k--)
        {
            string c1, c2;
            cin >> c1 >> c2;
            int num1 = index(c1), num2 = index(c2);
            head[num1].outadd();
            head[num2].inadd();
            if (type == 'U')
            {
                Matrix[num1][num2] = 1;
                Matrix[num2][num1] = 1;
            }
            else if (type == 'D')
            {
                Matrix[num1][num2] = 1;
            }
        }
    }
    ~Map()
    {
        delete[] Vex;
        delete[] head;
        for (int i = 0; i < Vexnum;i++)
            delete[] Matrix[i];
        delete[] Matrix;
    }
    void display()
    {
        for (int i = 0; i < Vexnum; i++)
            for (int j = 0; j < Vexnum; j++)
            {
                cout << Matrix[i][j];
                if (j != Vexnum - 1)
                    cout << " ";
                if (j == Vexnum - 1)
                    cout << endl;
            }
        for (int i = 0; i < Vexnum; i++)
        {
            cout << Vex[i];
            if (head[i].total != 0)
            {
                cout << ":";
                if (type == 'D')
                {
                    cout << " " << head[i].out
                         << " " << head[i].in
                         << " " << head[i].total;
                }
                else if (type == 'U')
                {
                    cout << " " << head[i].total;
                }
            }
            cout << endl;
        }
    }
};
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        char c;
        int k;
        cin >> c >> k;
        Map m(k, c);
        m.display();
    }
}

5. DS图—图非0面积

题目描述

编程计算由"1"围成的下列图形的面积。面积计算方法是统计"1"所围成的闭合曲线中"0"点的数目。如图所示,在10*10的二维数组中,"1"围住了15个点,因此面积为15。
在这里插入图片描述

输入

测试次数t

每组测试数据格式为:

数组大小m,n

一个由0和1组成的m*n的二维数组

输出

对每个二维数组,输出符号"1"围住的"0"的个数,即围成的面积。假设一定有1组成的闭合曲线,但不唯一。

输入样例

2
10 10
0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 1 1 0 0 0
0 0 0 0 1 0 0 1 0 0
0 0 0 0 0 1 0 0 1 0
0 0 1 0 0 0 1 0 1 0
0 1 0 1 0 1 0 0 1 0
0 1 0 0 1 1 0 1 1 0
0 0 1 0 0 0 0 1 0 0
0 0 0 1 1 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0
5 8
0 1 1 0 0 1 1 0
1 0 1 0 1 0 0 1
0 1 0 1 0 0 1 0
0 1 0 0 1 1 1 0
0 0 0 0 0 0 0 0

输出样例

15
5

参考代码

#include <iostream>
#include <queue>
using namespace std;
int n, m;
int nx[4] = {0, 0, 1, -1};
int ny[4] = {1, -1, 0, 0};
void bfs(int M[40][40], queue<int> x, queue<int> y, int a, int b)
{
    x.push(a);
    y.push(b);
    while (!x.empty())
    {
        for (int i = 0; i < 4; i++)
        {
            if (x.front() + nx[i] <= n && x.front() + nx[i] >= 0 && y.front() + ny[i] <= m && y.front() + ny[i] >= 0 && M[x.front() + nx[i]][y.front() + ny[i]] == 0)
            {
                x.push(x.front() + nx[i]);
                y.push(y.front() + ny[i]);
                M[x.front() + nx[i]][y.front() + ny[i]] = 1;
            }
        }
        x.pop();
        y.pop();
    }
}
int main()
{
    int T;
    cin >> T;
    while (T--)
    {
        int M[40][40] = {0};
        queue<int> x;
        queue<int> y;
        int num = 0;
        cin >> n >> m;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++)
                cin >> M[i][j];
        bfs(M, x, y, 0, 0);
        for (int i = 0; i <= n; i++)
        {
            for (int j = 0; j <= m; j++)
            {
                if (M[i][j] == 0)
                {
                    num++;
                }
            }
        }
        cout << num << endl;
    }
    return 0;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-08 10:59:23  更:2021-09-08 11:00:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 0:30:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码