华中科技大学数据结构与算法分析图的遍历实验代码

 

 输出结果为:

#include <iostream>
#include <iomanip>
#include <queue>
#include <cstdlib> 
#include <string.h>
using namespace std;
#define OK 1;
#define TRUE 1;
#define ERROR 0;
#define FALSE 0;
#define MAX_VERTEX_NUM 25 //最大顶点个数
#define DATA_NUM_PER_LINE 25
typedef enum { DG, DN, UDG, UDN } GraphKind;//{有向图,有向网,无向图,无向网}
typedef int InfoType;
typedef char* VertexType;
typedef int Status;
typedef int VRType;
bool visited[MAX_VERTEX_NUM]; //访问标志数组,定义成全局变量
Status(*VisitFunc)(int v); //函数变量
//图的邻接矩阵表示
typedef struct ArcCell {
    VRType adj;//VRType是顶点关系类型。对无权图,用1或0表示是否相邻;对带权图,则为权值类型;
    InfoType* info;//该户相关信息的指针
}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct {
    VertexType vexs[MAX_VERTEX_NUM];//顶点向量
    AdjMatrix arcs;//邻接矩阵
    int vexnum, arcnum;//图的当前顶点数合弧数
    GraphKind kind;//图的种类标志
}MGraph;

//图的邻接表表示
typedef struct ArcNode {
    int adjvex;//该弧所指顶点的位置
    struct ArcNode* nextarc;//该弧下一条弧的指针
    int weight;
    InfoType* info;//该弧相关信息的指针
}ArcNode;
typedef struct VNode {
    VertexType data;//顶点信息--名字 
    ArcNode* firstarc;//指向第一条依附该顶点的弧的指针
}VNode, AdjList[MAX_VERTEX_NUM];
typedef struct {
    AdjList vertices;
    int vexnum, arcnum;//图的当前顶点数合弧数
    GraphKind kind;//图的种类标志
}ALGraph;
Status CreateUDN_AdjMatrix(MGraph& G)
{
    G.vexnum = 25;
    for (int i = 0; i < 25; i++)
    {
        for (int j = 0; j < 25; j++)
        {
            G.arcs[i][j].adj = INT_MAX;
        }
    }
    G.arcs[0][1].adj = 137;   G.arcs[0][2].adj = 695;   G.arcs[0][15].adj = 668;
    G.arcs[1][10].adj = 674;  G.arcs[1][12].adj = 704;
    G.arcs[2][3].adj = 534;  G.arcs[2][10].adj = 349;  G.arcs[2][16].adj = 511;
    G.arcs[3][4].adj = 409;
    G.arcs[4][5].adj = 675; G.arcs[4][7].adj = 367;  G.arcs[4][19].adj = 902;  G.arcs[4][20].adj = 672;
    G.arcs[5][6].adj = 140;
    G.arcs[7][8].adj = 633;  G.arcs[7][9].adj = 825;
    G.arcs[9][10].adj = 651;
    G.arcs[11][12].adj = 397;
    G.arcs[12][13].adj = 305;
    G.arcs[13][14].adj = 241;
    G.arcs[15][22].adj = 1145;
    G.arcs[16][17].adj = 842; G.arcs[16][22].adj = 676;
    G.arcs[17][18].adj = 1100; G.arcs[17][19].adj = 967;
    G.arcs[18][19].adj = 639;
    G.arcs[19][20].adj = 607;
    G.arcs[20][21].adj = 255;
    G.arcs[22][23].adj = 216;   G.arcs[22][24].adj = 1892;
    for (int i = 0; i < G.vexnum; i++) {
        G.vexs[i] = (char*)malloc(20 * sizeof(char));
    }
    const char* name[] = { "北京","天津","哈尔滨","长春","沈阳","大连","呼和浩特","乌鲁木齐","西宁","兰州","西安","郑州",
                "徐州","上海","武汉","成都","昆明","贵阳","南宁","柳州","株洲","南昌","福州","广州","深圳" };
    for (int i = 0; i < G.vexnum; ++i)
    {
        strcpy(G.vexs[i], name[i]);
    }
    for (int i = 0; i < 25; i++)
    {
        for (int j = 0; j < 25; j++)
        {
            G.arcs[j][i].adj = G.arcs[i][j].adj;//由于构造的是无向网,所以还需要置<v1,v2>的对称弧<v2,v1> 
        }
    }
    return OK;
}
Status CreateUDN_AdjList(MGraph& g, ALGraph& G)
{
    int i, j;
    ArcNode* p;
    ALGraph* pG;
    pG = (ALGraph*)malloc(sizeof(ALGraph));
    if (pG) G = *pG;
    for (int i = 0; i < g.vexnum; i++) {
        G.vertices[i].data = (char*)malloc(20 * sizeof(char));
    }
    for (int i = 0; i < g.vexnum; ++i)
    {
        strcpy(G.vertices[i].data, g.vexs[i]);
    }
    for (i = 0; i < g.vexnum; i++)
        G.vertices[i].firstarc = NULL;
    for (i = 0; i < g.vexnum; i++)
    {
        for (j = g.vexnum - 1; j >= 0; j--)
        {
            if (g.arcs[i][j].adj != INT_MAX)
            {
                p = (ArcNode*)malloc(sizeof(ArcNode));
                p->adjvex = j;
                p->weight = g.arcs[i][j].adj;
                p->nextarc = G.vertices[i].firstarc;
                G.vertices[i].firstarc = p;
            }
        }
    }
    G.vexnum = g.vexnum;
    G.arcnum = g.arcnum;
    return OK;
}
Status LocateVex(MGraph& G, VertexType v)  //若找到结点返回i
{//查找顶点v 
    for (int i = 0; i <= G.vexnum; ++i)
    {
        if (!strcmp(G.vexs[i], v))
        {
            return i;
        }
    }
    return -1;  //否则返回-1,表示没有找到 
}
Status DestroyGraph(MGraph& G)
{//返回值:状态码,操作成功返回OK,作用:销毁图G
    //若是网 
    if (G.kind % 2) //重置邻接矩阵所有顶点之间不可达 
    {
        for (int i = 0; i < G.vexnum; i++)
        {
            for (int j = 0; j < G.vexnum; j++)
            {
                G.arcs[i][j].adj = INT_MAX;
            }
        }
    }
    else
    { //若是图 ,重置邻接矩阵所有顶点之间不可达
        for (int i = 0; i < G.vexnum; i++)
        {
            for (int j = 0; j < G.vexnum; j++)
            {
                G.arcs[i][j].adj = 0;
            }
        }
    }
    G.vexnum = 0;//重置顶点数为0
    G.arcnum = 0;//重置边数为0
    return OK;
}
Status PrintAdjMatrix(MGraph& G)
{//打印邻接矩阵
    int p = 1;
    cout << "AdjMatrix:" << endl;
    cout << "  ";
    for (int i = 0; i < G.vexnum; i++) //输出邻接矩阵的上坐标(全部顶点) 
    {
        cout <<setw(5)<< i+1;
    }
    cout << endl;
    for (int i = 0; i < G.vexnum; i++)//输出邻接矩阵的左坐标(全部顶点)和内容
    {
        cout << setw(2) <<i+1;//输出邻接矩阵左边的坐标
        for (int j = 0; j < G.vexnum; j++, p++)
        {
            if (G.arcs[i][j].adj == INT_MAX)
            {
                cout << "    ∞";
            }
            if (G.arcs[i][j].adj != INT_MAX)
            {
                cout << setw(5) << G.arcs[i][j].adj;
            }
            if (p % DATA_NUM_PER_LINE == 0)
                cout << endl;
        }
    }
    cout << "PrintAdjMatrix Over" << endl << endl;
    return OK;
}
Status PrintAdjList(ALGraph& G)
{//打印邻接表 
    cout << "AdjList:" << endl;
    for (int i = 0; i < G.vexnum; i++)
    {//顶点
        ArcNode* p = G.vertices[i].firstarc;
        cout << G.vertices[i].data<<'\t';
        while (p)
        {
            cout << '\t' <<"->" << G.vertices[i].data<<"("<<p->weight<<")";
            p = p->nextarc;
        }
        cout << endl;
    }
    cout << endl;
    return OK;
}
Status FirstAdjVex(MGraph G, VertexType v)
{//求顶点v在图G中的第一个邻接点
    int j = 0;//j表示不可达,在图中,0表示不可达,在网中INT_MAX表示不可达 
    int k = LocateVex(G, v); //v是顶点,不是序号!需要定位 //k就是顶点v在顶点数组中的序号
    if (G.kind == DN || G.kind == UDN)  //若是网,则INT_MAX表示不可达
    {
        j = INT_MAX;
    }
    for (int i = 0; i < G.vexnum; ++i) //在顶点v对应的第k行查找第一个邻接点的序号i 
    {
        if (G.arcs[k][i].adj != j)
        {
            return i;
        }
    }
    return -1;  //若未找到返回-1 
}
Status NextAdjVex(MGraph G, VertexType v, VertexType w)
{//求顶点v在图G中相对于邻接点w的下一个邻接点
    int j = 0;//j表示不可达,在图中,0表示不可达,在网中INT_MAX表示不可达
    int k1 = LocateVex(G, v);//k1是顶点v在顶点数组中的位序 
    int k2 = LocateVex(G, w);//k2是顶点w在顶点数组中的位序
    if (G.kind == DN || G.kind == UDN)//若是网,则使用INT_MAX表示不可达 
    {
        j = INT_MAX;
    }
    for (int i = k2 + 1; i < G.vexnum; ++i) //在图G中查找顶点v相对于顶点w的下一个邻接点的位置 
    {//若找到则返回i 
        if (G.arcs[k1][i].adj != j)
        {
            return i;
        }
    }
    return -1;//若未找到返回-1
}
void DFS_AdjMatrix(MGraph& G, int i)
{//从节点i开始DFS遍历
    int j;
    cout << G.vexs[i] << '\t';//输出起始结点 
    visited[i] = TRUE;//将已访问的结点标志成1
    for (j = 0; j < G.vexnum; j++)//依次搜索vi的邻接点 
    {
        if (G.arcs[i][j].adj != INT_MAX && !visited[j])//当满足有边且未被访问过时,递归调用去查找该邻接点 
        {
            DFS_AdjMatrix(G, j);//注意此处的G已经是指针类型,不需要再&G 
        }
    }
}
void DFSTraverse_AdjMatrix(MGraph G)
{//邻接矩阵的深度优先遍历
    int i;//初始化"标志"数组为0,代表未访问
    for (i = 0; i < G.vexnum; i++)
    {
        visited[i] = 0;
    }
    for (i = 0; i < G.vexnum; i++)
    {
        if (!visited[i])
        {
            DFS_AdjMatrix(G, i);
        }
    }
    cout << endl << endl;
}

void BFSTraverse_AdjMatrix(MGraph G)
{//邻接矩阵的广度优先遍历
    int i, j;//数组初始化为全0
    queue<int>Q;
    for (i = 0; i < G.vexnum; i++)
    {
        visited[i] = 0;
    }
    for (i = 0; i < G.vexnum; i++)
    {
        if (!visited[i])
        {
            cout << G.vexs[i] << '\t';//输出当前结点 
            visited[i] = 1;//将已访问的结点标志成1
            Q.push(i);//将已访问结点入队 
            while (!Q.empty())
            {
                j = Q.front();
                Q.pop();
                //接下来访问节点j的邻接节点 
                for (int m = 0; m < G.vexnum; m++) {
                    if (G.arcs[j][m].adj != INT_MAX && !visited[m]) //邻接且未访问 
                    {
                        cout << G.vexs[m] << '\t'; //输出顶点 
                        visited[m] = 1; //设置成已访问状态1 
                        Q.push(m);
                    }
                }
            }
        }
    }
    cout << endl << endl;
}

void DFS_AdjList(ALGraph& G, ArcNode* p)
{//从p所指节点开始DFS遍历,邻接链表
    cout << G.vertices[p->adjvex].data << '\t';//输出起始结点 
    visited[p->adjvex] = TRUE;//将已访问的结点标志成1
    p = G.vertices[p->adjvex].firstarc;
    while (p) {
        if (!visited[p->adjvex]) DFS_AdjList(G, p);
        p = p->nextarc;
    }
}
void DFSTraverse_AdjList(ALGraph G)
{//邻接表的深度优先遍历
    int i;//初始化"标志"数组
    ArcNode* p;
    for (i = 0; i < G.vexnum; i++)
    {
        visited[i] = 0;
    }
    for (i = 0; i < G.vexnum; i++)
    {
        if (!visited[i])
        {
            cout << G.vertices[i].data << '\t';//访问当前节点 
            visited[i] = TRUE;//将当前节点标记成已访问结点
            p = G.vertices[i].firstarc;
            while (p) //依次搜索vi的邻接点 
            {
                if (!visited[p->adjvex]) DFS_AdjList(G, p);
                p = p->nextarc;//查找下一个邻接节点
            }
        }
    }
    cout << endl << endl;
}

void BFSTraverse_AdjList(ALGraph G)
{//邻接表的广度优先遍历
    int i, j;
    queue<int> Q;
    ArcNode* p;
    for (i = 0; i < G.vexnum; i++)
    {
        visited[i] = 0;
    }
    for (i = 0; i < G.vexnum; i++)
    {
        if (!visited[i])
        {
            cout << G.vertices[i].data << '\t';//输出当前结点 
            visited[i] = 1;//将已访问的结点标志成1
            Q.push(i);//将已访问结点入队 
            while (!Q.empty())
            {
                j = Q.front();
                Q.pop();
                //接下来访问节点j的邻接节点 
                p = G.vertices[j].firstarc;
                while (p) {
                    if (!visited[p->adjvex]) {
                        cout << G.vertices[p->adjvex].data << '\t';//访问当前节点 
                        visited[p->adjvex] = TRUE;//将当前节点标记成已访问结点
                        Q.push(p->adjvex);
                    }
                    p = p->nextarc;
                }
            }
        }
    }
    cout << endl << endl;
}
int  main()
{
    system("color F0");
    MGraph  G1;
    ALGraph G2;
    CreateUDN_AdjMatrix(G1);
    cout << "所有顶点为:" << endl;
    for (int i = 0; i < G1.vexnum; i++)
    {
        cout <<setw(5)<<setfill(' ')<< i + 1 << "." << G1.vexs[i];
        if ((i+1)% 10 == 0) cout << endl;
    }
    cout << endl;
    CreateUDN_AdjList(G1, G2);
    PrintAdjMatrix(G1);//打印邻接矩阵
    PrintAdjList(G2);//打印邻接表
    cout << "邻接矩阵的深度优先遍历" << endl;
    DFSTraverse_AdjMatrix(G1);//邻接矩阵的深度优先遍历
    cout << "邻接矩阵的广度优先遍历" << endl;
    BFSTraverse_AdjMatrix(G1);//邻接矩阵的广度优先遍历
    cout << "邻接表的深度优先遍历" << endl;
    DFSTraverse_AdjList(G2);//邻接表的深度优先遍历
    cout << "邻接表的广度优先遍历" << endl;
    BFSTraverse_AdjList(G2);//邻接表的广度优先遍历
    system("pause");
    return 0;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值