【数据结构】无向图

谨以此文记录无向图的实现:

#include <iostream>
#define MaxInt 32767
#define MVNum 100

using namespace std;

typedef int QElemType;

typedef struct QNode
{
    
    
    QElemType data;
    QNode *next;
} QNode, *QueuePtr;

typedef struct
{
    
    
    QueuePtr front = nullptr, rear = nullptr;
} LinkQueue;

typedef char VertexType; //顶点数据类型
typedef int ArcType;     //边的权值类型
typedef struct
{
    
    
    VertexType vexs[MVNum];     //顶点表
    ArcType arcs[MVNum][MVNum]; //邻接矩阵
    int vexnum, arcnum;         //图的顶点数和边数
} AMGraph;

typedef int OtherInfo;
typedef struct ArcNode //边结构
{
    
    
    int adjvex;    //该边指向的顶点的位置
    ArcNode *next; //下一条边的指针
    OtherInfo info;
} ArcNode;

typedef struct VNode //顶点结构
{
    
    
    VertexType data; //顶点信息
    ArcNode *firstarc;
} VNode, AdjList[MVNum];

typedef struct //图结构
{
    
    
    AdjList vertics; //邻接表
    int vexnum, arcnum;
    int kind; //图的种类
} ALGraph;

bool visited[MVNum];

/**
 * @brief 初始化
 *
 * @param Q
 * @return true
 * @return false
 */
bool InitQueue(LinkQueue &Q)
{
    
    
    Q.front = Q.rear = new QNode;
    Q.front->next = nullptr;
    return true;
}

/**
 * @brief 销毁队列
 *
 * @param Q
 * @return true
 * @return false
 */
bool DestroyQueue(LinkQueue &Q)
{
    
    
    while (Q.front)
    {
    
    
        Q.rear = Q.front->next;
        delete Q.front;
        Q.front = Q.rear;
    }
    return true;
}

/**
 * @brief 判断队列是否为空
 *
 * @param Q
 * @return true
 * @return false
 */
bool QueueEmpty(LinkQueue Q)
{
    
    
    return Q.front == Q.rear;
}

/**
 * @brief 入队
 *
 * @param Q
 * @param e
 * @return true
 * @return false
 */
bool EnQueue(LinkQueue &Q, QElemType e)
{
    
    
    QNode *p = new QNode;
    p->data = e;
    p->next = nullptr;
    Q.rear->next = p;
    Q.rear = p;
    return true;
}

/**
 * @brief 出队
 *
 * @param Q
 * @param e
 * @return true
 * @return false
 */
bool DeQueue(LinkQueue &Q, QElemType &e)
{
    
    
    if (Q.front == Q.rear)
        return false;
    QNode *p = Q.front->next;
    e = p->data;
    Q.front->next = p->next;
    if (Q.rear == p)
        Q.rear = Q.front;
    delete p;
    return true;
}

void printUI()
{
    
    
    cout << "*******************************************" << endl;
    cout << "***************   无向网图   **************" << endl;
    cout << "*******************************************" << endl;
    cout << "*************  1.构建网图         *********" << endl;
    cout << "*************  2.输出邻接矩阵     *********" << endl;
    cout << "*************  3.深度优先遍历     *********" << endl;
    cout << "*************  4.广度优先遍历     *********" << endl;
    cout << "*************  5.退出             *********" << endl;
    cout << "*******************************************" << endl;
}

/**
 * @brief 确定顶点v在图G的顶点表中的下标
 *
 * @param G
 * @param v
 * @return int
 */
int LocateVex(AMGraph G, VertexType v)
{
    
    
    for (int i = 0; i < G.vexnum; i++)
    {
    
    
        if (G.vexs[i] == v)
            return i;
    }
    return -1;
}

/**
 * @brief 用邻接矩阵创建无向网图
 *
 * @param G
 * @return true
 * @return false
 */
bool CreateUDN(AMGraph &G)
{
    
    
    cout << "请输入顶点数和边数:";
    cin >> G.vexnum >> G.arcnum;
    cout << "请输入顶点信息:";
    for (int i = 0; i < G.vexnum; i++)
        cin >> G.vexs[i];
    //邻接矩阵初始化
    for (int i = 0; i < G.vexnum; i++)
        for (int j = 0; j < G.vexnum; j++)
            G.arcs[i][j] = 0;
    cout << "请输入边依附的顶点:" << endl;
    for (int k = 0; k < G.arcnum; k++)
    {
    
    
        VertexType v1, v2;
        ArcType w;
        cin >> v1 >> v2;
        int i = LocateVex(G, v1);
        int j = LocateVex(G, v2);
        G.arcs[i][j] = 1;
        G.arcs[j][i] = G.arcs[i][j];
    }
    return true;
}

/**
 * @brief 从邻接矩阵获得邻接表
 *
 * @param GA
 * @param G
 * @return true
 * @return false
 */
bool CreateUDG(AMGraph GA, ALGraph &G)
{
    
    
    G.vexnum = GA.vexnum;
    G.arcnum = GA.arcnum;
    for (int i = 0; i < G.vexnum; i++)
    {
    
    
        G.vertics[i].data = GA.vexs[i];
        G.vertics[i].firstarc = nullptr;
    }
    for (int i = 0; i < GA.vexnum; i++)
        for (int j = GA.vexnum - 1; j >= 0; j--)
        {
    
    
            if (GA.arcs[i][j])
            {
    
    
                ArcNode *p1 = new ArcNode;
                p1->adjvex = j;
                p1->next = G.vertics[i].firstarc;
                G.vertics[i].firstarc = p1;
            }
        }
    return true;
}

/**
 * @brief 输出邻接矩阵
 *
 * @param G
 */
void PrintUDN(AMGraph G)
{
    
    
    for (int i = 0; i < G.vexnum; i++)
    {
    
    
        for (int j = 0; j < G.vexnum; j++)
        {
    
    
            cout << G.arcs[i][j] << " ";
        }
        cout << endl;
    }
}

/**
 * @brief 从v开始深度优先遍历图G
 *
 * @param G
 * @param v
 */
void DFS_AM(AMGraph G, int v)
{
    
    
    cout << G.vexs[v] << " ";
    visited[v] = true;
    for (int w = 0; w < G.vexnum; w++)
    {
    
    
        if (G.arcs[v][w] != 0 && !visited[w])
            DFS_AM(G, w);
    }
}

void DFS_AL(ALGraph G, int v)
{
    
    
    cout << G.vertics[v].data << " ";
    visited[v] = true;
    ArcNode *p = G.vertics[v].firstarc;
    while (p != nullptr)
    {
    
    
        int w = p->adjvex;
        if (!visited[w])
            DFS_AL(G, w);
        p = p->next;
    }
}

/**
 * @brief 从v开始广度优先搜索图G
 *
 * @param G
 * @param v
 */
void BFS_AL(ALGraph G, int v)
{
    
    
    LinkQueue Q;
    QElemType u;
    cout << G.vertics[v].data << " ";
    visited[v] = true;
    InitQueue(Q);
    EnQueue(Q, v);
    while (!QueueEmpty(Q))
    {
    
    
        DeQueue(Q, u);
        for (ArcNode *p = G.vertics[u].firstarc; p != nullptr; p = p->next)
        {
    
    
            int w = p->adjvex;
            if (!visited[w])
            {
    
    
                cout << G.vertics[w].data << " ";
                visited[w] = true;
                EnQueue(Q, w);
            }
        }
    }
}

int main()
{
    
    
    AMGraph G;
    ALGraph algraph;
    int mode;
    printUI();
    while (true)
    {
    
    
        cout << "请输入选择:";
        cin >> mode;
        if (mode == 5)
            break;
        switch (mode)
        {
    
    
        case 1:
            CreateUDN(G);
            break;
        case 2:
            PrintUDN(G);
            break;
        case 3:
            for (int i = 0; i < G.vexnum; i++)
                visited[i] = false;
            CreateUDG(G, algraph);
            DFS_AL(algraph, 0);
            cout << endl;
            break;
        case 4:
            for (int i = 0; i < G.vexnum; i++)
                visited[i] = false;
            CreateUDG(G, algraph);
            BFS_AL(algraph, 0);
            cout << endl;
            break;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_51507437/article/details/124975357
今日推荐