无向网的邻接矩阵表和邻接链表表示以及各自的深度优先搜索和广度优先搜索

#include <iostream>
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#define MAX 20                              //定义数组的最大值
#define EXT 10000
using namespace std;
typedef struct UDN
{
    char vex[MAX];                          //顶点向量
    int arcs[MAX][MAX];                     //邻接矩阵
    int vexnum,arcnum;                      //无向图当前顶点数和弧数
}Udn;
typedef struct ArcNode
{
    int adjvex;                             //该弧所指向的顶点位置
    struct ArcNode *nextarc;                //指向下一条弧的指针
    int w;                                  //权值
}ArcNode;
typedef struct VNode
{
    char data;                               //顶点信息
    ArcNode *fristarc;                       //指向第一条依附该顶点的弧指针
}VNode,AdjList[MAX];
typedef struct
{
    AdjList vertices;
    int vexnum,arcnum;                        //图的顶点数和弧数
}ULGraph;
typedef struct QNode                         //创建队列节点
{
    char data;
    struct QNode *next;
}QNode,*Queue;
typedef struct
{
    Queue front;                             //头指针
    Queue rear;                              //尾指针
}LinkQueue;
int InitQueue(LinkQueue &Q)                   //创建一个空队列
{
    Q.front=Q.rear=(Queue)malloc(sizeof(QNode));
    Q.front->next=NULL;
    return 1;
}
bool QueueEmpty(LinkQueue Q)                 //判断队列是否为空
{
    if(Q.front==Q.rear)
        return true;
    return false;
}
int EnQueue(LinkQueue &Q,int e)            //入队(尾)
{
    Queue p;
    p=(Queue)malloc(sizeof(QNode));
    p->data=e;
    p->next=NULL;
    Q.rear->next=p;
    Q.rear=p;                              //尾指针后移
    return 1;
}
int DeQueue(LinkQueue &Q,int &e)            //出队(头)
{
    Queue p;
    if(Q.front==Q.rear)
        return 0;                          //空队列返回0
    p=Q.front->next;
    e=p->data;
    Q.front->next=p->next;
    if(Q.rear==p)
        Q.rear=Q.front;                    //尾指针回送
    free(p);
    return 1;
}
 void CreateUDN(Udn &U)                        //创捷邻接矩阵
 {
     printf("请输入无向网的顶点数和弧数:");
     scanf("%d%d",&U.vexnum,&U.arcnum);
     printf("请输入%d个顶点向量:",U.vexnum);
     for(int i=0;i<U.vexnum;i++)             //输入顶点信息
     {
         getchar();
         scanf("%c",&U.vex[i]);
     }
     for(int i=0;i<U.vexnum;i++)
        for(int j=0;j<U.vexnum;j++)            //将多有权值付付为正无穷
            U.arcs[i][j]=EXT;
     puts("请输入弧的起始点和终点以及权值(eg:a b 3):");
     int m,n,w;
     char ch1,ch2;
     for(int i=0;i<U.arcnum;i++)
     {
         cin>>ch1>>ch2>>w;                     //输入网的信息
         for(int j=0;j<U.vexnum;j++)
         {
             if(ch1==U.vex[j])
                m=j;
         }
         for(int j=0;j<U.vexnum;j++)
         {
             if(ch2==U.vex[j])
                n=j;
         }
         U.arcs[m][n]=w;                       //因为是无向的,所以邻接矩阵是对称的
         U.arcs[n][m]=w;
     }
 }
 void Display1(Udn U)                          //显示连接矩阵
 {
     printf("\t");
     for(int i=0;i<U.vexnum;i++)
        printf("%c\t",U.vex[i]);
     puts("");
     for(int i=0;i<U.vexnum;i++)
     {
         printf("%c\t",U.vex[i]);
         for(int j=0;j<U.vexnum;j++)
         {
             if(U.arcs[i][j]==EXT)
                printf("∞\t");
             else
                printf("%d\t",U.arcs[i][j]);
         }
         puts("");
     }
 }
 void CreateULGraph(ULGraph &ULG,Udn &U)                     //以邻接矩阵为基础建立邻接表
 {
     ULG.arcnum=U.arcnum;
     ULG.vexnum=U.vexnum;
     for(int i=0;i<U.vexnum;i++)
     {
         ULG.vertices[i].data=U.vex[i];
         ULG.vertices[i].fristarc=NULL;
     }
     for(int i=0;i<U.vexnum;i++)
         for(int j=0;j<U.vexnum;j++)
             if(U.arcs[i][j]!=EXT)
             {
                 ArcNode *p=(ArcNode*)malloc(sizeof(ArcNode));
                 p->adjvex=j;
                 p->w=U.arcs[i][j];
                 p->nextarc=ULG.vertices[i].fristarc;
                 ULG.vertices[i].fristarc=p;
             }
 }
 void Display2(ULGraph ULG)                             //邻接表的输出
 {
     puts(" '邻接矩阵转为邻接表' 为(下标~权值):");
     for(int i=0;i<ULG.vexnum;i++)
     {
         printf("%c  %d",ULG.vertices[i].data,i);
         ArcNode *p=ULG.vertices[i].fristarc;
         while(p!=NULL)
         {
             printf("---> ");
             printf("%d~%d",p->adjvex,p->w);
             p=p->nextarc;
         }
         printf(" ^");
         puts("");
     }
 }
void BturntoJ(ULGraph G)                            //链接表转换为邻接矩阵
{
    Udn U;
    U.vexnum=G.vexnum;
    U.arcnum=G.arcnum;
    for(int i=0;i<G.vexnum;i++)
    {
        U.vex[i]=G.vertices[i].data;
        for(int j=0;j<G.vexnum;j++)
            U.arcs[i][j]=EXT;
    }
    for(int i=0;i<G.vexnum;i++)
    {
        ArcNode *p=G.vertices[i].fristarc;
        while(p!=NULL)
        {
            U.arcs[i][p->adjvex]=p->w;
            U.arcs[p->adjvex][i]=p->w;
            p=p->nextarc;
        }
    }

    Display1(U);
}
bool visited[MAX];
void setfalse(ULGraph *G)
{
    for(int i=0;i<G->vexnum;i++)                //初始化图的各个顶点为false,未访问过
         visited[i]=false;
}
void DFSB(ULGraph *G,int i)                     //邻接表深度优先算法
 {
     visited[i]=true;
     printf("%c ",G->vertices[i].data);
     ArcNode *p=G->vertices[i].fristarc;
     while(p)
     {
         if(!visited[p->adjvex])             如果边表结点没有被访问过,则递归调用DFS
            DFSB(G,p->adjvex);
         p=p->nextarc;
     }
 }
void DFSTraverseB(ULGraph *G)
 {
     puts("无向网的 '邻接表深度优先' 搜索:");
     for(int i=0;i<G->vexnum;i++)
     {
         if(!visited[i])                     //选取一个未访问过的顶点进行深度优先遍历,如果是连通图DFS只执行一次
            DFSB(G,i);
     }
     puts("");
 }
 void DFSL(Udn *U,int v)                      //邻接矩阵的深度优先遍历
 {
     if(!visited[v])
     {
         printf("%c ",U->vex[v]);
         visited[v]=true;
     }
     for(int i=0;i<U->vexnum;i++)
        if(U->arcs[v][i]!=EXT&&!visited[i])
            DFSL(U,i);
 }
 int LocataVex(ULGraph G,char ch)              //返回顶点在网中的位置,无则返回-1
 {
     for(int i=0;i<G.vexnum;i++)
        if(ch==G.vertices[i].data)
            return i;
     return -1;
 }
 int FristAdjVex(ULGraph G,char v)           //返回v的第一个邻接点打的序号
 {
     int posi_v=LocataVex(G,v);
     ArcNode *p;
     p=G.vertices[posi_v].fristarc;
     if(p)
        return p->adjvex;
     else
        return -1;
 }
 int NextAdjVex(ULGraph G,char v,char w)
 {
     ArcNode *p;
     int pos_v,pos_w;
     pos_v=LocataVex(G,v);
     pos_w=LocataVex(G,w);
     p=G.vertices[pos_v].fristarc;
     while(p&&p->adjvex!=pos_w)
        p=p->nextarc;
     if(!p||!p->nextarc)
        return -1;
     else
        return p->nextarc->adjvex;
 }
 void BFSB(ULGraph G)                                   //无向网链接表的广度优先遍历
 {
     puts("无向网 '链接表的广度优先' 搜索:");
     LinkQueue Q;
     InitQueue(Q);                                    //置空一个辅助队列
     int u;
     for(int i=0;i<G.vexnum;i++)
     {
         if(!visited[i])
         {
             visited[i]=true;
             printf("%c ",G.vertices[i].data);
             EnQueue(Q,i);                            //入队
             while(!QueueEmpty(Q))
             {
                 DeQueue(Q,u);                          //对头出队,并付给u
                 for(int j=FristAdjVex(G,G.vertices[u].data);j>=0;j=NextAdjVex(G,G.vertices[u].data,G.vertices[j].data))
                    if(!visited[j])
                    {
                        visited[j]=true;
                        printf("%c ",G.vertices[j].data);
                        EnQueue(Q,j);
                    }
             }
         }
     }
     puts("");
 }
 void BFSL(Udn U,int v)                       //邻接矩阵的广度优先遍历为
 {
     puts("无向网 ‘邻接矩阵的广度优先’ 搜索为;");
     LinkQueue Q;
     InitQueue(Q);
     int x;
     for(int j=0;j<U.vexnum;j++)
     {
         if(!visited[j])
         {
            printf("%c ",U.vex[j]);
            visited[j]=true;
            EnQueue(Q,j);
         }
         while(!QueueEmpty(Q))
         {
            DeQueue(Q,x);
            for(int i=0;i<U.vexnum;i++)
                if(U.arcs[x][i]!=EXT&&!visited[i])
                {
                    printf("%c ",U.vex[i]);
                    visited[i]=true;
                    EnQueue(Q,i);
                }
        }
     }
 }
int main()
{
    puts("*********************无向网********************\n");
    Udn u;
    CreateUDN(u);
    puts("无向网 ‘向量矩阵’ 表示为:");
    Display1(u);
    ULGraph ul;
    CreateULGraph(ul,u);
    Display2(ul);
    puts("无向网 ‘邻接表转为邻接矩阵‘ 为:");
    BturntoJ(ul);
    setfalse(&ul);
    DFSTraverseB(&ul);
    puts("");
    setfalse(&ul);
    puts("无向网的 ’邻接矩阵深度优先‘ 搜索:");
    for(int i=0;i<u.vexnum;i++)
        DFSL(&u,i);
    puts("\n");
    setfalse(&ul);
    BFSB(ul);
    puts("");
    setfalse(&ul);
    BFSL(u,0);
    return 0;
}
/*
8 5
a b c d e f g h
a h 5
a f 4
b h 3
d e 2
e h 1
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值