无向图的几种基本操作

版权声明:欢迎分享(指明出处),若有错误还请指正!!! https://blog.csdn.net/zj19941201/article/details/81068576

一. 实验目的和要求
1、掌握图的存储结构:邻接矩阵、邻接表。
2、掌握图的深度优先与广度优先两个搜素算法。
3、学会对图的存储结构进行基本操作。
4、加强综合程序的分析、设计能力。
二. 实验内容
1、现有14个人(分别用字母A、B、… N表示),他们相互之间的朋友关系如图所示(有线相连表示是朋友关系),请分别用邻接矩阵与邻接表表示该关系图,并完成以下功能。
*这里写图片描述*

① 以邻接矩阵表示,在此结构上完成:
 创建此图;
 输出此图的邻接矩阵;
 输出从A出发的深度优先搜索序列;
 输出从A出发的广度优先搜索序列;
 输入两个人p1、p2,判断此两人是否为朋友关系,若不是,给出一种从p1能找到p2的路径;(如输入p1=‘A’、p2=‘N’,则A与N不是直接朋友关系,但可以(不唯一)通过A-B-F-K-N方式联系到N。)
② 以邻接表表示,在此结构上完成:
 创建此图;
 输出此图的邻接表;
 输出从A出发的深度优先搜索序列;
 输出从A出发的广度优先搜索序列;
 输入两个人p1、p2,判断此两人是否为朋友关系,若不是,给出一种从p1能找到p2的路径;(如输入p1=‘A’、p2=‘N’,则A与N不是直接朋友关系,但可以(不唯一)通过A-B-F-K-N方式联系到N。)
③ 建立头文件AdjMatrix.h和AdjLink.h,分别包含邻接矩阵结构和邻接表结构的操作实现函数,建立主程序文件test6.cpp,在主函数中通过调用来实现上述功能。
④ 自行增加合适的功能,可作为额外的实验成绩进行加分(例如考虑添加或删除一对朋友关系;找出朋友最多的那个人;上面找到A到N的联系路径,若要求找到一条最短的路线怎么找等等)。**


// 主函数
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX_VERTEX_NUM  20   //最大顶点个数 
#define TRUE    1
#define FALSE   0
#define STACK_INIT_SIZE         100
#define STACKINCREMENT          10  
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
typedef int Status;
typedef int QElemtype;                                                          //队列 
typedef struct QNode{
    QElemtype data;
    struct QNode *next;
}QNode,*QueuePtr;
typedef struct{
    QueuePtr front;
    QueuePtr rear;
    QueuePtr p; 
}LinkQueue;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
typedef int SElemtype;
typedef struct{                                                             //栈 
    SElemtype   *base;  
    SElemtype   *top;    
    int         stacksize;
}SqStack;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
typedef char VertexType;
typedef int  VRType;                                                            //图 (邻接矩阵声明) 
typedef struct{
    VertexType Vexs[MAX_VERTEX_NUM];                 //顶点向量 
    VRType edges[MAX_VERTEX_NUM][MAX_VERTEX_NUM];           //邻接矩阵 
    int vexnum,arcnum;                              //图的当前顶点数和弧数 
}MGraph;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
typedef char Vertextype;
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;              //图的当前顶点数,边数                            
}ALGraph;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
bool visited[MAX_VERTEX_NUM];                                               //全局变量布尔数组:访问 
#include"AdjMatrix.h"
#include"AdjLink.h"
int main()
{
    printf("~~~~~~~~~~~~邻接矩阵~~~~~~~~~~~~\n"); 
    MGraph G;
    CreateGraph(G);
    SqStack S,S1;
    InitStack(S);       
    FILE *fp,*fp1;                      //用文件输入更省时省力; 
    fp=fopen("INPUT2.txt","r");
    CreateUDG(G,fp);                    
    printf("邻接矩阵为:\n"); 
    PRINT(G);                           //输出邻接矩阵    
    printf("深度优先搜索顺序为:");           //深度遍历 
    DFSTraverse(G); 
    putchar(10);
    getchar();
    printf("广度优先搜索顺序为:");
    BFSTraverse(G);
    putchar(10);
    char ch1,ch2;
    printf("请输入任意不相同的两个大写字母:");
    scanf("%c %c",&ch1,&ch2);
    LinkQueue Q;
    Init(Q);      
    panding(G,S,Q,ch1,ch2);
    friendsnum(G);                                  //找出朋友最多的人 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/  
    printf("\n~~~~~~~~~~~邻接表~~~~~~~~~~~~~:");
    ALGraph* G1 =(ALGraph*)malloc(sizeof(ALGraph)) ;
    fp1=fopen("INPUT2.txt","r");
    CreateALGraph(G1,fp1);
    PRINTL(G1);
    printf("深度优先搜索顺序为:");
    DFSTraverseL(G1); 
    putchar(10);
    printf("广度优先搜索顺序为:");
    BFSTraverseL(G1);
    putchar(10);
    printf("请输入任意不相同的两个大写字母:");
    getchar();
    char ch3,ch4;
    scanf("%c %c",&ch3,&ch4);
    LinkQueue Q1;
    InitStack(S1);
    Init(Q1);
    pandingL(G1,S1,Q1,ch3,ch4);
    friendsnumL(G1);                                        //找出朋友最多的人 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
}

//头文件

//邻接矩阵方式

void CreateGraph(MGraph &G)
{
    printf("请输入顶点数和边数:");
    scanf("%d",&G.vexnum);
    scanf("%d",&G.arcnum);
    getchar();

    printf("请输入结点信息:");
    for(int i=0;i<G.vexnum;i++)
        scanf("%c",&G.Vexs[i]);

    //邻接矩阵初始化
    for(int j=0;j<G.vexnum;j++)
        for(int k=0;k<G.vexnum;k++)
            G.edges[j][k]=0;
}

void CreateUDG(MGraph &G,FILE *fp)
{
    for(int t=0;t<G.arcnum;t++)  
      {   char ch1,ch2;int o;int p;
          fscanf(fp,"%c,%c",&ch1,&ch2); 
          for(int i=0;i<G.vexnum;i++) //定位功能 
            {
                if(ch1==G.Vexs[i])
                o=i;
            }
            for(int i=0;i<G.vexnum;i++) //定位功能 
            {
                if(ch2==G.Vexs[i])
                p=i;
            }
          G.edges[o][p]=1;
          G.edges[p][o]=1; 
      }     
}

void PRINT(MGraph &G)
{
    for(int i=0;i<G.vexnum;i++)
    {
        for(int j=0;j<G.vexnum;j++)
            printf("|%d| ",G.edges[i][j]);
        putchar(10);
    }
}

void DFS(MGraph &G,int i)
{
    int k;
    visited[i]=TRUE;
    putchar(G.Vexs[i]);
    for(k=0;k<G.vexnum;k++)
    {
        if(G.edges[i][k]==1&&visited[k]==0){
            DFS(G,k);
        }
    }
}

void DFSTraverse(MGraph &G)
{
    int i;
    for(i=0;i<G.vexnum;i++) // visited数组的初始化
        visited[i]=FALSE;
    for(i=0;i<G.vexnum;i++){
            if(visited[i]==0)
            DFS(G,i);
        }
}

void BFSTraverse(MGraph &G)
{
    for(int i=0;i<G.vexnum;i++)
        visited[i]=0;
    putchar(G.Vexs[0]);
    visited[0]=1;
    for(int i=0;i<G.vexnum;i++)
    {
        for(int j=0;j<G.vexnum;j++)
        {
        if(G.edges[i][j]==1&&visited[j]==0)
            {
                putchar(G.Vexs[j]); 
                visited[j]=1;   
            }               
            }   
        }

}

void InitStack(SqStack &S){
    S.base=(SElemtype *)malloc(STACK_INIT_SIZE*sizeof(SElemtype));
    if(!S.base)exit(-2);
    S.top=S.base;
    S.stacksize=STACK_INIT_SIZE;
}  

void Push(SqStack &S,SElemtype e)  
{
    if(S.top-S.base>=S.stacksize)  
    {S.base=(SElemtype *)realloc(S.base,  
                        (S.stacksize+STACKINCREMENT)*sizeof(SElemtype));  
        if(!S.base)exit(-2);  
        S.top=S.base+S.stacksize;  
        S.stacksize+=STACKINCREMENT;   
    }  
    *S.top++=e;    
} 

int Pop(SqStack &S)  
{
    if(S.top==S.base)return 0;  
    S.top--;  
   int e=*S.top;
    return e;            
}  

int GetTop(SqStack &S)  
{
    if(S.top==S.base)return 0;  
   int e=*(S.top-1);  
    return e;  
}

void Init(LinkQueue &Q)  
{
    Q.front=Q.rear=Q.p=(QueuePtr)malloc(sizeof(QNode));  
    if(!Q.front)exit(-2);  
    Q.front->next=NULL;    
} 

void EnQueue(LinkQueue &Q,int e)  
{    
    QueuePtr p=(QueuePtr)malloc(sizeof(QNode));  
    if(!p)exit(-2);  
    p->data=e;p->next=NULL;  
    Q.rear->next=p;  
    Q.rear=p;    
} 

int DeQueue(LinkQueue &Q)  
{ 
    if(Q.front==Q.rear)return 0;  
    QueuePtr p=Q.front->next;  
    int e=p->data;  
    Q.front->next=p->next;  
    if(Q.rear==p)Q.rear=Q.front;  
    free(p);
    return e;    
} 

void relationship(MGraph &G,SqStack &S,LinkQueue &Q,int s,int m)//实现两点间最短距离 函数 
{
    int dist[G.vexnum],path[G.vexnum];
    for(int i=0;i<G.vexnum;i++){
        dist[i]=-1;
        path[i]=-1;     
    }
    EnQueue(Q,s);
    dist[s]=0;
    while(Q.front!=Q.rear)
    {
        int w=DeQueue(Q);
        for(int j=0;j<G.vexnum;j++)
            if(G.edges[w][j]==1&&dist[j]==-1){
                dist[j]=dist[w]+1;
                path[j]=w;
                EnQueue(Q,j);
            }
    }

    while(m!=-1)
    {
        Push(S,m);
        m=path[m];
    }
    int dz;
    printf("最短路径为:");
    while(S.base!=S.top-1)
    {
        dz=Pop(S);
        printf("%c->",G.Vexs[dz]);
    }
    dz=Pop(S);
    printf("%c",G.Vexs[dz]);
}

void panding(MGraph &G,SqStack &S,LinkQueue &Q,char ch1,char ch2)
{
    int start,end;
    for(int i=0;i<G.vexnum;i++){
        if(ch1==G.Vexs[i])
        {   
            start=i;
            break;
        }
    }
    for(int i=0;i<G.vexnum;i++){
        if(ch2==G.Vexs[i])
        {end=i;
        break;
        }
    }
    if(G.edges[start][end]==1) printf("%c和%c是朋友",ch1,ch2);
    else{
        relationship(G,S,Q,start,end);

    }   
}

void friendsnum(MGraph &G)
{   int max=0,sum=0,l=0;int i=0;
    for(i=0;i<G.vexnum;i++){
        for(int j=0;j<G.vexnum;j++)
        {
            sum+=G.edges[i][j];
        }
        if(max<sum)
        {
            max=sum;
            l=i;
        }
        sum=0;
    }       
    printf("\n朋友最多的是%c,共有%d个",G.Vexs[l],max);   
}

//邻接表方式

void CreateALGraph(ALGraph* G1,FILE *fp1)
{
    ArcNode  *L;
    putchar(10);
    printf("请输入顶点数和边数:");
    scanf("%d %d",&G1->vexnum,&G1->arcnum);
    getchar();
    printf("请输入结点信息:");
    for(int i=0;i<G1->vexnum;i++)
    {
        scanf("%c",&G1->vertices[i].data);//G1->vertices[i].data存放顶点信息 
        G1->vertices[i].firstarc=NULL;
    }
    char ch1,ch2;int h,q;
    for(int i=0;i<G1->arcnum;i++)
    {
        fscanf(fp1,"%c,%c",&ch1,&ch2);
        for(int i=0;i<G1->vexnum;i++){
            if(ch1==G1->vertices[i].data){
                 q=i;break;
            }
        }
        for(int i=0;i<G1->vexnum;i++){
            if(ch2==G1->vertices[i].data){
                 h=i;break;
            }
        }
        L=(ArcNode*)malloc(sizeof(ArcNode));
        L->adjvex=h;
        L->nextarc=G1->vertices[q].firstarc;
        G1->vertices[q].firstarc=L;
        L=(ArcNode*)malloc(sizeof(ArcNode));
        L->adjvex=q;
        L->nextarc=G1->vertices[h].firstarc;
        G1->vertices[h].firstarc=L; 
    }
} 
void PRINTL(ALGraph* G1)
{

    for (int i=0;i<G1->vexnum;i++)  
   {  

       printf("%d:",i);
        ArcNode *L=G1->vertices[i].firstarc;  
       while(L!=NULL)  
       {    
            printf("%d->",L->adjvex);  
            L=L->nextarc;  
       }
       printf("NULL");
       printf("\n");  
   } 
}

void BFSTraverseL(ALGraph* G1)
{
    for(int i=0;i<G1->vexnum;i++)
        visited[i]=0;
    int a[G1->vexnum];  
    a[0]=0;
    visited[0]=1;
    int j=1;            //初始化
    for (int i=0;i<G1->vexnum;i++)  
   {   ArcNode  *L=G1->vertices[i].firstarc;
       while(L!=NULL)  
       {    
                int t=L->adjvex;
                if(visited[t]==0)
                {
                    a[j]=L->adjvex;
                    visited[t]=1;
                        j++;
                }    
            L=L->nextarc;     
       } 
   }
   int t;
   for(int i=0;i<G1->vexnum;i++)
    {
        t=a[i];
        printf("%c",G1->vertices[t].data);
    } 
}

void DFS(ALGraph* G1,int i)
{
    int k;
    visited[i]=1;
    printf("%c",G1->vertices[i].data);
    ArcNode  *L=G1->vertices[i].firstarc;
    while(L)
    {
        if(!visited[L->adjvex]){
            DFS(G1,L->adjvex);
        }
        return;
    }   
    L=L->nextarc;
}

void DFSTraverseL(ALGraph* G1)
{

    for(int i=0;i<G1->vexnum;i++)   // visited数组的初始化
        visited[i]=0;
    for(int i=0;i<G1->vexnum;i++){
            if(visited[i]==0)
            DFS(G1,i);
        }   
}
void relationshipL(ALGraph*G1,SqStack &S1,LinkQueue &Q1,int s,int m)    //实现两点间最短距离 函数 
{
    int dist[G1->vexnum],path[G1->vexnum];
        for(int i=0;i<G1->vexnum;i++){
        dist[i]=-1;
        path[i]=-1;     
    }
    EnQueue(Q1,s);
    dist[s]=0;
    while(Q1.front!=Q1.rear)
    {
        int w=DeQueue(Q1);
        ArcNode  *L=G1->vertices[w].firstarc;
        while(L){
            if(dist[L->adjvex]==-1){
                dist[L->adjvex]=dist[w]+1;
                path[L->adjvex]=w;
                EnQueue(Q1,L->adjvex);  
            }
            L=L->nextarc;   
        }
    }
    while(m!=-1)
    {
        Push(S1,m);
        m=path[m];
    }
    int dz;
    printf("最短路径为:");
    while(S1.base!=S1.top-1)
    {
        dz=Pop(S1);
        printf("%c->",G1->vertices[dz].data);
    }
    dz=Pop(S1);
    printf("%c",G1->vertices[dz].data);
}

void pandingL(ALGraph* G1,SqStack &S1,LinkQueue &Q1,char ch3,char ch4)
{
    int start,end;
    for(int i=0;i<G1->vexnum;i++){
        if(ch3==G1->vertices[i].data)
        {   
            start=i;
            break;
        }
    }
    for(int i=0;i<G1->vexnum;i++){
        if(ch4==G1->vertices[i].data)
        {
            end=i;
            break;
        }
    }
    ArcNode  *L=G1->vertices[start].firstarc;
    int flag=0;
    while(L){
        if(L->adjvex==end){
            flag=1;
            break;
        }
        L=L->nextarc;
    }
    if(flag==1)
        printf("%c%c是朋友",ch3,ch4);
    else
    {
        relationshipL(G1,S1,Q1,start,end);
    }           
}

void friendsnumL(ALGraph* G1)
{
    int max=0,sum=0,l=0;

    for(int i=0;i<G1->vexnum;i++){
        ArcNode  *L=G1->vertices[i].firstarc;
            while(L){
                L=L->nextarc;
                sum++;  
            }
            if(max<sum){
            max=sum;
            l=i;
            }
        sum=0;
        }
    printf("\n朋友最多的是%c,共有%d个",G1->vertices[l].data,max);
}

猜你喜欢

转载自blog.csdn.net/zj19941201/article/details/81068576