数据结构-有向图的创建与遍历

#include "stdio.h"
#include "string.h"
#define MaxInt 32767    // 表示极大值,即∞
#define MVNum 100       // 最大顶点数
#define VerTexType char // 假设顶点的数据类型为字符型
#define ArcType int     // 假设边的权值类型为整型
typedef struct
{
    VerTexType vexs[MVNum];     // 顶点表
    ArcType arcs[MVNum][MVNum]; // 邻接矩阵
    int vexnum, arcnum;         // 图的当前点数和边数
} AMGraph, *AMGraph_str;
// 定义队列类型和相关操作
#define QUEUE_SIZE 100
typedef struct
{
    char data[QUEUE_SIZE];
    char front, rear;
} Queue;
int LocateVex(AMGraph G, VerTexType u);
AMGraph CreateDN(void);
void printf_DN(AMGraph G);
void DN_init(AMGraph *G);
void DN_add_elements(AMGraph *G);
void find_element(AMGraph G);
void main()
{
    AMGraph G;
    G = CreateDN();
    printf_DN(G);
    DN_add_elements(&G);
    printf_DN(G);
    find_element(G);

    printf("深度优先遍历:\n");
    dfs_traverse(&G);
    printf("\n广度优先遍历:\n");
    bfs_traverse(&G);
    system("pause");
}
void printf_DN(AMGraph G)
{
    int i = 0, j = 0;
    printf("\n头部总顶点数:%d,总边数:%d\n", G.vexnum, G.arcnum);
    printf("打印图的内容:\n    ");
    for (i = 0; i < G.vexnum; i++)
        printf("[%c]", G.vexs[i]);
    printf("\n");
    for (i = 0; i < G.vexnum; i++)
    {
        printf("[%c]:", G.vexs[i]);
        for (j = 0; j < G.vexnum; j++)
            printf("[%c]", G.arcs[i][j] == MaxInt ? 'N' : (G.arcs[i][j] + '0'));
        printf("\n");
    }
}
void DN_init(AMGraph *G)
{
    int i = 0, j = 0;
    for (i = 0; i < G->vexnum; i++) // 初始化邻接矩阵,边的权值均置为极大值
        for (j = 0; j < G->vexnum; j++)
            G->arcs[i][j] = MaxInt;
    printf("邻接矩阵初始化完成\n");
    // printf_DN(&G);
}
AMGraph CreateDN(void) // 创建有向图
{
    AMGraph G;
    int i = 0, j = 0, k = 0;
    ArcType w = 0;
    char data = 0;
    char v1 = 0, v2 = 0;
    // 采用邻接矩阵表示法,创建有向网G
    printf("请输入总顶点数:");
    scanf_s("%d", &G.vexnum, 2);
    printf("\n请输入总边数:");
    scanf("%d", &G.arcnum);
    printf("\n总顶点数:%d,总边数:%d\n", G.vexnum, G.arcnum);
    printf("请输入各点信息\n");
    getchar();
    for (i = 0; i < G.vexnum; i++) // 依次输入点的信息
    {
        printf("[%d]=", i);
        fflush(stdin); // 清空缓冲区
        scanf("%c", &G.vexs[i]);
        printf("\n");
    }
    DN_init(&G);
    printf_DN(G);
    printf("开始构造邻接矩阵\n");
    printf("请输入连接点与权重,格式:v1,v2,w,方向:v1->v2,权重:w\n");
    for (i = 0, j = 0, k = 0; k < G.arcnum; k++)
    { // 构造邻接矩阵
        printf("[%d]:", k);
        fflush(stdin); // 清空缓冲区
        scanf("%c,%c,%d", &v1, &v2, &w);
        printf("结果[%C][%c][%d]\n", v1, v2, w);
        i = LocateVex(G, v1);
        j = LocateVex(G, v2); // 确定v1和v2在G中的位置
        printf("arcs[%d][%d]=%d\n", i, j, w);
        if (i == -1 || j == -1)
        {
            printf("该元素不存在");
            k--;
        }
        else
            G.arcs[i][j] = w; // 边<v1, v2>的权值置为w
        G.arcs[i][j] = w;     // 边<v1, v2>的权值置为w
    }
    return G;
} //
void DN_add_elements(AMGraph *G)
{
    int i = 0, j = 0, k = 0, len1 = 0, len2 = 0, w = 0;
    char v1 = 0, v2 = 0;
    printf("请输入要插入参数个数:");
    fflush(stdin); // 清空缓冲区
    scanf("%d", &len1);
    if (G->vexnum + len1 > MVNum)
    {
        printf("总顶点数超过限制");
        return;
    }
    G->vexnum += len1;

    printf("请输入要添加的边的个数:");
    fflush(stdin); // 清空缓冲区
    scanf("%d", &len2);
    G->arcnum += len2;
    printf("\n总顶点数:%d,总边数:%d\n", G->vexnum, G->arcnum);

    printf("请输入各点信息\n");
    for (i = G->vexnum - len1; i < G->vexnum; i++)
    {
        printf("[%d]=", i);
        fflush(stdin); // 清空缓冲区
        scanf("%c", &G->vexs[i]);
    }
    printf_DN(*G);
    printf("请输入连接点与权重,格式:v1,v2,w,方向:v1->v2,权重:w\n");
    for (i = 0, j = 0, k = G->arcnum - len2; k < G->arcnum; k++)
    { // 构造邻接矩阵
        printf("[%d]:", k);
        fflush(stdin); // 清空缓冲区
        scanf("%c,%c,%d", &v1, &v2, &w);
        printf("结果[%C][%c][%d]\n", v1, v2, w);
        i = LocateVex(*G, v1);
        j = LocateVex(*G, v2); // 确定v1和v2在G中的位置

        printf("arcs[%d][%d]=%d\n", i, j, w);
        if (i == -1 || j == -1)
        {
            printf("该元素不存在");
            k--;
        }
        else
            G->arcs[i][j] = w; // 边<v1, v2>的权值置为w
    }
}
void find_element(AMGraph G)
{
    int i = 0, j = 0;
    char key = 0;
    printf("请输入要查询的关键字:");
    fflush(stdin); // 清空缓冲区
    scanf("%c", &key);
    i = LocateVex(G, key);
    if (i == -1)
    {
        printf("该元素不存在");
        return;
    }
    printf("查询结果:\n[%c]:", G.vexs[i]);
    for (j = 0; j < G.vexnum; j++)
        printf("[%c]", G.arcs[i][j] == MaxInt ? 'N' : (G.arcs[i][j] + '0'));
    for (j = 0; j < G.vexnum; j++)
    {
        if (G.arcs[i][j] != MaxInt)
        {
            printf("\n第一个邻接点是:%c\n", G.vexs[j]);
            break;
        }
    }
}
int LocateVex(AMGraph G, VerTexType u)
{ // 存在则返回u在顶点表中的下标;否则返回-1
    int i;
    for (i = 0; i < G.vexnum; ++i)
        if (u == G.vexs[i])
            return i;
    return -1;
}

void init_queue(Queue *q)
{
    q->front = q->rear = 0;
}

int is_queue_empty(Queue *q)
{
    return q->front == q->rear;
}

int enqueue(Queue *q, int x)
{
    if ((q->rear + 1) % QUEUE_SIZE == q->front)
    {
        return 0; // 队列已满
    }
    q->data[q->rear] = x;
    q->rear = (q->rear + 1) % QUEUE_SIZE;
    return 1; // 入队成功
}

int dequeue(Queue *q, int *x)
{
    if (is_queue_empty(q))
    {
        return 0; // 队列已空
    }
    *x = q->data[q->front];
    q->front = (q->front + 1) % QUEUE_SIZE;
    return 1; // 出队成功
}

// 深度优先遍历
void dfs(int v, int visited[], AMGraph *G)
{
    int i;
    printf("%c ", G->vexs[v]);
    visited[v] = 1;
    for (i = 0; i < G->vexnum; i++)
    {
        if (G->arcs[v][i] != MaxInt && !visited[i])
        {
            dfs(i, visited, G);
        }
    }
}

void dfs_traverse(AMGraph *G)
{
    int visited[MVNum] = {0};
    int i;
    char string = 0;
again_DFS:
    printf("请输入访问节点:");
    fflush(stdin); // 清空缓冲区
    scanf("%c", &string);
    // 对每个未访问过的节点进行广度优先遍历
    i = LocateVex(*G, string);
    if (i == -1)
    {
        printf("输入元素不存在,请重新输入");
        goto again_DFS;
    }

    for (; i < G->vexnum; i++)
    {
        if (!visited[i])
        {
            dfs(i, visited, G);
        }
    }
}

// 广度优先遍历
void bfs_traverse(AMGraph *G)
{
    int visited[MVNum] = {0};
    Queue q;
    int i, v;
    char string = 0;
again:
    printf("请输入访问节点:");
    fflush(stdin); // 清空缓冲区
    scanf("%c", &string);
    // 对每个未访问过的节点进行广度优先遍历
    i = LocateVex(*G, string);
    if (i == -1)
    {
        printf("输入元素不存在,请重新输入");
        goto again;
    }

    for (; i < G->vexnum; i++)
    {
        if (!visited[i])
        {
            visited[i] = 1;
            printf("%c ", G->vexs[i]);
            enqueue(&q, i);
            while (!is_queue_empty(&q))
            {
                dequeue(&q, &v);
                for (i = 0; i < G->vexnum; i++)
                {
                    if (G->arcs[v][i] && !visited[i])
                    {
                        visited[i] = 1;
                        printf("%c ", G->vexs[i]);
                        enqueue(&q, i);
                    }
                }
            }
        }
    }
}

使用案例截图:

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

睿智の男孩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值