2.3 实验3 图的应用

目的要求
1.掌握图的存储策略及其存储实现。
2.掌握图的深度、广度优先遍历的算法策略及其程序实现。
3.掌握图的常见算法策略及其程序实现。
实验内容
1.键入或随机生成数据,建立一个有向图的邻接表。
2.输出该邻接表。
3.以有向图邻接表为基础上,计算各顶点的度并输出。
4.以有向图邻接表为基础,输出其拓扑排序序列。
5.采用邻接表存储,实现无向图的非递归DFS遍历。
6.采用邻接表存储,实现无向图的BFS优先遍历。
7.判断无向图任意两个顶点间是否有路径,若有则输出路径上的顶点序列。
8.在主函数中设计一个简单的菜单,调用上述算法。
实验说明
1.类型定义(邻接表存储)
const int MAX_ VERTEX_NUM=8; // 顶点的最大个数
typedef struct ArcNode;
{
int adjvex ;
struct ArcNode *nextarc ;
int weight; // 边的权
} ArcNode ; // 表结点
typedef VertexType int; // 顶点元素类型
typedef struct VNode
{
int degree, indegree; // 顶点的度,入度
VertexType data;
ArcNode *firstarc;
} VNode /头结点/, AdjList[MAX_VERTEX_NUM] ;
typedef struct
{
AdjList vertices;
int vexnum, arcnum; // 顶点的实际数,边的实际数
} ALGraph ;
2.上述类型定义可根据情况适当调整。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <string.h>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <list>
#include <bitset>
#include <stack>
#include <stdlib.h>
using namespace std;

#define MAXSIZE 20
int indegree[MAXSIZE], outdegree[MAXSIZE];//
typedef char InfoType;//邻接表存储结构类型
typedef char VertexType;//节点数据类型
typedef struct Arcnode//表结点
{
    int adjvex;//存放结点的下表
    Arcnode* nextarc;//指向下一条弧的指针域
    InfoType* info;//该弧相关信息的指针
}Arcnode;
typedef struct VNode//头结点
{
    VertexType data;
    Arcnode* firstarc;
}VNode, AdjList[MAXSIZE];
typedef struct
{
    AdjList vertices;
    int vexnum;//顶点数
    int arcnum;//边数
    int kind;//0为无向图,1为有向图
}ALGraph;
int visited[MAXSIZE];//辅助数组,标志是否访问过

void Create_Graph(ALGraph& G)//
{
    char ch1, ch2;
    int k1, k2;
    cout << "输入顶点数和边数" << endl;
    cin >> G.vexnum >> G.arcnum;//
    cout << "输入图的顶点" << endl;
    for (int i = 1; i <= G.vexnum; i++)
    {
        getchar();
        cin >> G.vertices[i].data;
        G.vertices[i].firstarc = NULL;
    }
    cout << "请输入边" << endl;
    for (int i = 1; i <= G.arcnum; i++)
    {
        getchar();
        cin >> ch1 >> ch2;
        for (int j = 1; j <= G.arcnum; j++)
            if (G.vertices[j].data == ch1)
            {
                k1 = j;
                break;
            }
        for (int j = 1; j <= G.arcnum; j++)
            if (G.vertices[j].data == ch2)
            {
                k2 = j;
                break;
            }
        Arcnode* p;//把新申请的表结点前插
        p = new Arcnode();
        p->adjvex = k2;
        p->nextarc = G.vertices[k1].firstarc;
        G.vertices[k1].firstarc = p;
    }
}

void Output_Graph(ALGraph G)
{
    for (int i = 1; i <= G.vexnum; i++)
    {
        cout << G.vertices[i].data << ' ';
        Arcnode* p;
        p = G.vertices[i].firstarc;
        while (p)
        {
            cout << G.vertices[p->adjvex].data << ' ';
            p = p->nextarc;
        }
        cout << endl;
    }
}

void Degree_Query(ALGraph G)//询问入度和出度
{
    Arcnode* p = NULL;
    for (int i = 1; i <= G.vexnum; i++)
    {
        p = G.vertices[i].firstarc;
        while (p)
        {
            //indegree[i]++;
            indegree[p->adjvex]++;
            outdegree[i]++;
            p = p->nextarc;
        }
    }
}

void dfs(ALGraph G, VertexType x)
{
    int k;
    for (int i = 1; i <= G.vexnum; i++)//先找到结点X
    {
        if (G.vertices[i].data == x)
        {
            k = i;
            break;
        }
    }
    cout << G.vertices[k].data << ' ';
    visited[k] = 1;
    Arcnode* p;
    p = G.vertices[k].firstarc;
    while (p)//如果该结点的第一临接点存在
    {
        if (visited[p->adjvex] == 0)
        {
            dfs(G, G.vertices[p->adjvex].data);
        }
        p = p->nextarc;
    }
}

void bfs(ALGraph G, VertexType x)
{
    struct
    {
        Arcnode* Q[MAXSIZE];
        int front, rear;
    }QQ;
    Arcnode* p;
    QQ.front = QQ.rear = 0;//init
    int k;
    for (int i = 1; i <= G.vexnum; i++)
    {
        if (G.vertices[i].data == x)
        {
            k = i;
            break;
        }
    }
    visited[k] = 1;
    cout << G.vertices[k].data << ' ';
    QQ.rear = (QQ.rear + 1) % MAXSIZE;
    QQ.Q[QQ.rear] = G.vertices[k].firstarc;
    while (QQ.front != QQ.rear)
    {
        QQ.front = (QQ.front + 1) % MAXSIZE;
        p = QQ.Q[QQ.front];
        while (p)
        {
            if (!visited[p->adjvex])
            {
                visited[p->adjvex] = 1;
                cout << G.vertices[p->adjvex].data << " ";
                QQ.rear = (QQ.rear + 1) % MAXSIZE;
                QQ.Q[QQ.rear] = G.vertices[p->adjvex].firstarc;
            }
            p = p->nextarc;
        }
    }
}

int Topological_Sort(ALGraph G)
{
    int s[MAXSIZE];//stack
    int top = 0;
    for (int i = 1; i <= G.vexnum; i++)
    {
        if (indegree[i] == 0)
        {
            top++;
            s[top] = i;
        }
    }
    int ans = 0;
    int i = 1;
    Arcnode* p = NULL;
    while (top)
    {
        i = s[top--];
        cout << i << ' ' << G.vertices[i].data << endl;
        ans++;
        for (p = G.vertices[i].firstarc; p; p = p->nextarc)
        {
            int k = p->adjvex;
            indegree[k]--;
            if (!indegree[k])
            {
                s[++top] = k;
            }
        }
    }
    if (ans < G.vexnum)
        return -1;
    return 1;
}

void menu()
{
    printf("*********有向图邻接表*********\n");
    printf("1.输出邻接表\n");
    printf("2.计算各顶点的度\n");
    printf("3.输出拓扑排序序列\n");
    printf("4.DFS遍历\n");
    printf("5.BFS优先遍历\n");
    printf("6.判断无向图任意两个顶点间是否有路径,若有则输出路径上的顶点序列\n");
   
    printf("0.退出\n\n");

}
int main()
{

    ALGraph G;
    char chx;
    Create_Graph(G);//
    int choice;
    int flag = 0;//拓扑排序
    menu();
    while (1)
    {
        printf("选择你的操作:");
        scanf_s("%d", &choice);
        switch (choice)
        {
        case 1:
            cout << "邻接表为:" << endl;
            Output_Graph(G);


            break;
        case 2:
            memset(indegree, 0, sizeof(indegree));
            memset(outdegree, 0, sizeof(outdegree));
            Degree_Query(G);
            cout << "邻接表的度为" << endl;
            for (int i = 1; i <= G.vexnum; i++)//输出入度
                cout << indegree[i] << ' ';
            cout << endl;
            for (int i = 1; i <= G.vexnum; i++)//输出出度
                cout << outdegree[i] << ' ';
            cout << endl;



            break;
        case 3:
            memset(visited, 0, sizeof(visited));
            cout << "请输入深搜开始的结点:(以0结束)" << endl;
            cin >> chx;          
                cout << chx << "开始的深搜顺序为:";
                dfs(G, chx);
                cout << endl;
               memset(visited, 0, sizeof(visited));
            
            printf("\n");
            break;
        case 4:
            cout << "请输入广搜开始的结点:(以0结束)" << endl;
            cin >> chx;
          
                cout << chx << "开始的广搜顺序为";
                bfs(G, chx);
                cout << endl;
               memset(visited, 0, sizeof(visited));
         


            printf("\n");
            break;

        case 5:
          
            cout << "拓扑排序" << endl;
            flag = Topological_Sort(G);
            cout << endl;
            if (flag == -1)
                cout << "不能进行拓扑排序" << endl;
            else
                cout << "已经进行拓扑排序" << endl;

            printf("\n");
            break;
        case 6:
            //没实现
            printf("\n");
            break;
        case 7:

            break;
        case 0:
            return 0;
        default:
            printf("输入错误,请重新输入\n");
        }
    }
 
    return 0;
    

    

   
    
   
}



运行结果与输出示例
在这里插入图片描述
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值