图的基本操作-数据结构C++

问题描述

(1)基于邻接表存储结构实现图的基本操作,并在main主函数中来实现图中边/弧的插入操作。

①建立图;

②图的深度优先遍历;

③图的广度优先遍历

④图中边/弧的插入。

问题描述:

①从键盘输入顶点数及边/弧数并输入顶点信息、边/弧的顶点起始编号和终止编号;要求:图采用链式存储。

②分别调用深度优先搜索遍历或者广度优先遍历算法对建立好的图进行遍历。要求分别显示遍历后的结点序列。

③根据输入要插入边/弧的顶点起始编号和终止编号,将其插入到图中,并在屏幕中以两种遍历中的一种将结点序列进行显示或者以链接表形式输出。

程序清单:

(1)【广度与深度和插入一体】

#include<iostream>

#include<stdio.h>

#include<stdlib.h>

using namespace std;

#define MAX_VERTEX_NUM 20

typedef int VertexType;//深度用

typedef int ElemType;//链队用

typedef enum { DG, DN, UDG, UDN }GraphKind;

//枚举变量

typedef struct QNode {

    ElemType data;

    struct QNode* next;

}QNode, * QueuePtr;

typedef struct {

    QueuePtr front;

    QueuePtr rear;

}LinkQueue;

int visited[MAX_VERTEX_NUM];

typedef struct ArcNode

//表结点结构体

{

    int adjvex;

    struct ArcNode* nextarc;

}ArcNode;

typedef struct VNode

//表头结点

{

    VertexType data;

    ArcNode* firstarc;

}VNode, AdjList[MAX_VERTEX_NUM];

typedef struct

//定义图

{

    AdjList vertices;

    int vexnum, arcnum;

    //vex定点 arc边

    GraphKind Kind;

}ALGraph;

ALGraph Create_Graph()

//初始化建立

{

    ArcNode* p;

    int i, s, d;

    ALGraph adjg;

    adjg.Kind = DG;

    cout << "请输入顶点数和边数:";

    cin >> s >> d;

    adjg.vexnum = s;//定点

    adjg.arcnum = d;//边

    for (i = 0; i < adjg.vexnum; i++)

    {

        cout << "第" << i + 1 << "个顶点信息:";

        cin >> adjg.vertices[i].data;

        adjg.vertices[i].firstarc = NULL;

    }

    for (i = 0; i < adjg.arcnum; i++)

    {

        cout << "第" << i + 1 << "条边的起始顶点编号和终止顶点编号:";

        cin >> s >> d;

        while (s<1 || s>adjg.vexnum || d<1 || d>adjg.vexnum)

        {

            cout << "编号超出范围,重新输入:";

            cin >> s >> d;

        }

        s--;

        d--;

        p = (ArcNode*)malloc(sizeof(ArcNode));

        //分配内存空间

        p->adjvex = d;

        p->nextarc = adjg.vertices[s].firstarc;

        adjg.vertices[s].firstarc = p;

    }

    return adjg;

}

void DFS(ALGraph G, int v)

//深度优先

{

    ArcNode* p;



    visited[v - 1] = 1;

    v--;

    cout << G.vertices[v].data;

    p = G.vertices[v].firstarc;

    while (p)

    {

        int j = p->adjvex;

        if (visited[j] == 0)

            DFS(G, j + 1);

        p = p->nextarc;

    }

}

void DFS_straverse_Grapg(ALGraph G)

//全图

{

    int v;

    for (v = 0; v < G.vexnum; v++)

        visited[v] = 0;

    for (v = 0; v < G.vexnum; v++)

        if (!visited[v])

            DFS(G, v + 1);

}

void insertion(ALGraph& adjg)

//插入边

{

    ArcNode* p;

    int s, d;

    cout << "请输入要插入的边的起始顶点编号和终止顶点编号:";

    cin >> s >> d;

    while (s<1 || s>adjg.vexnum || d<1 || d>adjg.vexnum)

    {

        cout << "编号超出范围,重新输入:";

        cin >> s >> d;

    }

    s--;

    d--;

    p = (ArcNode*)malloc(sizeof(ArcNode));

    p->adjvex = d;

    p->nextarc = adjg.vertices[s].firstarc;

    adjg.vertices[s].firstarc = p;

}

/// <链队列>

bool InitQueue(LinkQueue& Q)

//初始化链队列

{

    Q.front = Q.rear = new QNode;//头节点

    if (!Q.front || !Q.rear)return 0;

    Q.front->next = NULL;

    return 1;

}

bool EnQueue(LinkQueue& Q, ElemType e)

//元素入队

{

    QueuePtr temp = new QNode;

    if (!temp)return 0;

    temp->data = e;

    temp->next = NULL;

    Q.rear->next = temp;

    Q.rear = temp;

    return 1;

}

bool DeQueue(LinkQueue& Q, ElemType& e)

//出队

{

    if (Q.front == Q.rear)

        return 0;

    QueuePtr temp = Q.front->next;//指向第一个结点的指针

    e = temp->data;

    Q.front->next = temp->next;

    if (Q.rear == temp)//若出队的是尾指针指向结点,则需要调整尾指针,否则删除后尾指针指向空

        Q.rear = Q.front;

    delete temp;

    return 1;

}

bool DestroyQueue(LinkQueue& Q)

//销毁队列

{

    QueuePtr temp = Q.front;

    while (Q.front) {

        Q.front = Q.front->next;

        delete temp;

        temp = Q.front;

    }

    return 1;

}

bool QueueEmpty(LinkQueue Q)

{

    if (Q.front == Q.rear)

        return 1;

    else

        return 0;

}

void BFS_traverse(ALGraph G, int vi)

//广度遍历

{

    int visited[MAX_VERTEX_NUM];

    int i, v;

    ArcNode* p;

    LinkQueue Q;

    InitQueue(Q);

    for (i = 0; i < G.vexnum; i++)

        visited[i] = 0;

    visited[vi - 1] = 1;

    cout << G.vertices[vi - 1].data;

    EnQueue(Q, vi);

    while (!QueueEmpty(Q))

    {

        DeQueue(Q, v);

        v--;

        p = G.vertices[v].firstarc;

        while (p != NULL)

        {

            int j = p->adjvex;

            if (visited[j] == 0)

            {

                visited[j] = 1;

                cout<< G.vertices[j].data;

                EnQueue(Q, j + 1);

            }

            p = p->nextarc;

        }

    }

}

int main()

{

    ALGraph g;

    g = Create_Graph();

    //初始化 建表

    cout << "DFS:" << endl;//深度

    DFS_straverse_Grapg(g);

    //顶点遍历

    cout << endl;//间隔

    cout << "BFS:" << endl;//广度

    BFS_traverse(g, 1);

    cout << endl;//间隔

    insertion(g);

    //插入一个边

    cout << " DFS_straverse_Grapg:" << endl;//深度

    DFS_straverse_Grapg(g);

    //遍历全图

    cout << endl;

    cout << "BFS:" << endl;//广度

    BFS_traverse(g, 1);

    return 0;

}

运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值