美文网首页
图(邻接链表)(C语言)

图(邻接链表)(C语言)

作者: Recalcitrant | 来源:发表于2019-06-13 20:55 被阅读0次

邻接链表实现图

/*
邻接链表表示法
*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <iomanip>

#define InfoType int        //权值
#define VertexType int      //顶点数据类型

#define OK 0                //操作成功执行
#define ERROR -1            //操作失败
#define OVERFLOW -2         //溢出
typedef int Status;

#define MAX_VERTEX_NUM 20       //最大顶点数
#define MAX_EDGE_NUM 40         //最大边数


#define QElemType VertexType
#include "queue.h"

enum Boolean { FALSE, TRUE };
Boolean visited[MAX_VERTEX_NUM]; //访问标志矢量数组

typedef struct ArcNode
{
    int adjvex;                 //边的邻接顶点
    struct ArcNode *nextarc;    //该顶点邻接的下一条边
    InfoType *info;             //权值类型
} ArcNode;
typedef struct VNode {
    VertexType data;            //顶点信息
    ArcNode *firstarc;          //该顶点邻接的一条边
}VNode, AdjList[MAX_VERTEX_NUM];
typedef struct {
    AdjList vertices;
    int vexnum, arcnum;
    int Kind;
}ALGraph;

Status LocateVex(ALGraph &G, int v)
{
    int k, n = 0;
    for (k = 0; k < G.vexnum; k++)
    {
        if (G.vertices[k].data == v)
        {
            n = k;
            break;
        }
    }
    return n;
}

Status FirstAdjvex(ALGraph &G, int v)
{
    if (G.vertices[v].firstarc != NULL)
        return (G.vertices[v].firstarc->adjvex);
    else
        return OVERFLOW;
}

Status NextAdjvex(ALGraph &G, int v, int w)
{
    ArcNode *p;
    p = G.vertices[v].firstarc;
    while (p&&p->adjvex != w)
        p = p->nextarc;
    if (p)
    {
        if (p->nextarc != NULL)return(p->nextarc->adjvex);
        else return OVERFLOW;
    }
    else
        return OVERFLOW;
}

Status Build_AdjList(ALGraph &G)
{
    int v, v1, v2, i, j;
    ArcNode *q, *p;
    printf("请输入图的顶点数:\n");
    scanf("%d", &G.vexnum);
    if (G.vexnum < 0) return ERROR;
    printf("请输入图的边数:\n");
    scanf("%d", &G.arcnum);
    if (G.arcnum < 0) return ERROR;
    for (v = 0; v < G.vexnum; v++) {
        printf("顶点V%d:\n", v);
        scanf("%d", &G.vertices[v].data);
        G.vertices[v].firstarc = NULL;
    }
    for (v = 1; v <= G.arcnum; v++)
    {
        printf("请输入边的两个邻接顶点(逗号隔开):\n");
        scanf("%d,%d", &v1, &v2);
        if ((i = LocateVex(G, v1)) < 0) return ERROR;
        if ((j = LocateVex(G, v2)) < 0) return ERROR;
        p = (ArcNode*)malloc(sizeof(ArcNode));
        if (!G.vertices[i].firstarc)
            G.vertices[i].firstarc = p;
        else {
            for (q = G.vertices[i].firstarc; q->nextarc != NULL; q = q->nextarc);
            q->nextarc = p;
        }
        p->adjvex = j;
        p->nextarc = NULL;
    }
    return OK;
}

Status printelem(VertexType d)
{
    printf("V%d->", d);
    return OK;
}

Status(*VisitFunc)(VertexType d);

void DFS(ALGraph &G, int v)
{
    ArcNode *w;
    visited[v] = TRUE;
    //VisitFunc(v);
    VisitFunc(G.vertices[v].data);
    for (w = G.vertices[v].firstarc; w; w = w->nextarc)
        if (!visited[w->adjvex]) DFS(G, w->adjvex);
}

void DFSTreaverse(ALGraph G, Status(*Visit)(VertexType d))
{
    VisitFunc = Visit;
    int v, n;
    for (v = 0; v < G.vexnum; ++v) visited[v] = FALSE;
    printf("请输入深度优先遍历起始顶点:\n");
    scanf("%d", &n);
    printf("深度优先遍历点顺序:\n");
    DFS(G, n - 1);
    for (v = 0; v < G.vexnum; ++v)
        if (!visited[v]) DFS(G, v);
}

void BFS(ALGraph &G, int v)
{
    int u, w;
    LinkQueue Q;
    InitQueue(Q);
    visited[v] = TRUE;
    VisitFunc(G.vertices[v].data);
    //VisitFunc(v);
    EnQueue(Q, v);
    while (!QueueEmpty(Q)) {
        DeQueue(Q, u);
        for (w = FirstAdjvex(G, u); w >= 0; w = NextAdjvex(G, u, w))
            if (!visited[w]) {
                visited[w] = TRUE;
                VisitFunc(G.vertices[w].data);
                //VisitFunc(w);
                EnQueue(Q, w);
            }//endif
    }//endwhile
    DestroyQueue(Q);
}

void BFSTreaverse(ALGraph G, Status(*Visit)(VertexType d))
{
    char n;
    int v;
    VisitFunc = Visit;
    for (v = 0; v < G.vexnum; ++v) visited[v] = FALSE;
    printf("请输入广度优先遍历起始顶点:\n"); fflush(stdin);
    scanf("%c", &n);
    printf("广度优先遍历点顺序:\n"); fflush(stdin);
    BFS(G, LocateVex(G, n));
    for (v = 0; v < G.vexnum; ++v)
        if (!visited[v]) BFS(G, v);
}

int main(int argc, char *argv[])
{
    ALGraph G;
    Build_AdjList(G);
    DFSTreaverse(G, printelem);
    printf("\n");
    BFSTreaverse(G, printelem);
    printf("\n");
    return 0;
}

队列头文件queue.h

#pragma once
#define OVERFLOW -1
#define OK 1
#define ERROR 0
#define QUEUE_INIT_SIZE 100
#define QUEUEINCREMENT 10
typedef int Status;
typedef struct QNode
{
    QElemType   data;
    struct QNode *next;
}QNode, *QueuePtr;
typedef struct
{
    QueuePtr front;
    QueuePtr rear;
}LinkQueue;
Status InitQueue(LinkQueue &Q);
Status DestroyQueue(LinkQueue &Q);
Status ClearQueue(LinkQueue &Q);
Status QueueEmpty(LinkQueue Q);
int QueueLength(LinkQueue Q);
Status GetHead(LinkQueue &Q, QElemType &e);
Status EnQueue(LinkQueue &Q, QElemType e);
Status DeQueue(LinkQueue &Q, QElemType &e);
Status QueueTraverse(LinkQueue Q, Status(*visit)());

Status InitQueue(LinkQueue &Q)
{
    Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));
    if (!Q.front)exit(OVERFLOW);
    Q.front->next = NULL;
    return OK;
}
Status DestroyQueue(LinkQueue &Q)
{
    while (Q.front)
    {
        Q.rear = Q.front->next;
        free(Q.front);
        Q.front = Q.rear;
    }
    return OK;
}
Status ClearQueue(LinkQueue &Q)
{
    Q.front = Q.rear;
    return OK;
}
Status QueueEmpty(LinkQueue Q)
{
    if (Q.front == Q.rear)return OK;
    else
        return ERROR;
}
Status EnQueue(LinkQueue &Q, QElemType e)
{
    QueuePtr p;
    p = (QueuePtr)malloc(sizeof(QNode));
    if (!p) exit(OVERFLOW);
    p->data = e;
    p->next = NULL;
    Q.rear->next = p;
    Q.rear = p;
    return OK;
}
Status DeQueue(LinkQueue &Q, QElemType &e)
{
    QueuePtr p;
    if (Q.front == Q.rear) return ERROR;
    p = Q.front->next;
    e = p->data;
    Q.front->next = p->next;
    if (Q.rear == p) Q.rear = Q.front;
    free(p);
    return OK;
}
int QueueLength(LinkQueue Q)
{
    return(Q.rear - Q.front);
}
Status GetHead(LinkQueue &Q, QElemType &e)
{
    if (Q.front == Q.rear) return ERROR;
    else return Q.front->data;
}
Status QueueTraverse(LinkQueue Q, Status(*visit)(QElemType e))
{
    QueuePtr p = Q.front->next;
    while (p != NULL)
    {
        visit(p->data);
        p = p->next;
    }
    return OK;
}

相关文章

  • 图(邻接链表)(C语言)

    邻接链表实现图 队列头文件queue.h

  • 5 图的复习目录

    5.1 图 5.2 图的存储结构 邻接矩阵 邻接表 十字链表 邻接多重链表 5.3 图的遍历 深度优先 广...

  • 【算法】基本的图算法

    图的搜索技巧是整个图算法领域的核心。 图的表示 有两种标准方法:1.邻接链表2.邻接矩阵 邻接链表是将一个结点所有...

  • 面试准备之【数据结构】1——图

    一. 有向图/无向图 共有:邻接表,邻接矩阵 有向图独有:十字链表,边集数组 无向图独有:邻接多重表 1.邻接矩...

  • 基本的数据结构有哪些

    图: 有向图:无向图: 图的存储结构:1,邻接矩阵(数组表达)2,邻接表和十字链表,链表表达,主要表达有向图3,邻...

  • 数据结构-图

    数据结构 - 图 目录: 基本概念无向图有向图 储存结构邻接矩阵邻接表十字链表(有向图)邻接多重表(无向图) 图的...

  • 五. 图

    图的存储 顺序表(矩阵存储) 链表(邻接链表) 图的遍历 BFS, DFS 图的最小生成树 Prim, Krusk...

  • 数据结构-学习二

    图: 无向图,有向图度,子图,路径,环,连通图,连通子图。 存储: 邻接矩阵二维数组。 邻接表+数组加链表优先搜...

  • 算法

    1.图的存储结构 邻接矩阵表示法 便于运算邻接表表示法 对于稀疏图来讲,更节省存储空间十字链表邻接多重表 ...

  • 第三章 图论

    3.1 图的存储: 图结构存储主要有2种形式:邻接矩阵和邻接链表 (1)在邻接矩阵存储方法中,除了一个记录各个顶点...

网友评论

      本文标题:图(邻接链表)(C语言)

      本文链接:https://www.haomeiwen.com/subject/vamefctx.html