第十二周项目二操作用邻接表存储的图

问题代码:

/*问题及代码 
 *Copyright(c)2016,烟台大学计算机学院 
 *All right reserved. 
 *文件名称:ll .cpp 
 *作者:李玲 
 *完成日期;2016年11月16日  
 *版本号;v1.0 
 *问题描述: 
          
假设图G采用邻接表存储,分别设计实现以下要求的算法:  
(1)输出出图G中每个顶点的出度;  
(2)求出图G中出度最大的一个顶点,输出该顶点编号;  
(3)计算图G中出度为0的顶点数;  
(4)判断图G中是否存在边<i,j>。  
利用下图作为测试用图,输出结果。  
这里写图片描述  
 *输入描述:图的邻接矩阵 
 *程序输出:图中各顶点出度,最大出度顶点信息,出度为0的顶点,某边是否存在。 
*/  
#include <stdio.h>  
#include <malloc.h>  
#include "graph.h"  
  
int main()  
{  
    ALGraph *G;  
    int A[7][7]=  
    {  
        {0,1,1,1,0,0,0},  
        {0,0,0,0,1,0,0},  
        {0,0,0,0,1,1,0},  
        {0,0,0,0,0,0,1},  
        {0,0,0,0,0,0,0},  
        {0,0,0,1,1,0,1},  
        {0,1,0,0,0,0,0}  
    };  
    ArrayToList(A[0], 7, G);  
    printf("(1)各顶点出度:\n");  
    OutDs(G);  
    printf("(2)最大出度的顶点信息:");  
    OutMaxDs(G);  
    printf("(3)出度为0的顶点:");  
    ZeroDs(G);  
    printf("(4)边<2,6>存在吗?");  
    if(Arc(G,2,6))  
        printf("是\n");  
    else  
        printf("否\n");  
    printf("\n");  
    return 0;  
}  
#include <stdio.h>  
#include <malloc.h>  
#include "graph.h"  
  
//功能:由一个反映图中顶点邻接关系的二维数组,构造出用邻接矩阵存储的图  
//参数:Arr - 数组名,由于形式参数为二维数组时必须给出每行的元素个数,在此将参数Arr声明为一维数组名(指向int的指针)  
//      n - 矩阵的阶数  
//      g - 要构造出来的邻接矩阵数据结构  
void ArrayToMat(int *Arr, int n, MGraph &g)  
{  
    int i,j,count=0;  //count用于统计边数,即矩阵中非0元素个数  
    g.n=n;  
    for (i=0; i<g.n; i++)  
        for (j=0; j<g.n; j++)  
        {  
            g.edges[i][j]=Arr[i*n+j]; //将Arr看作n×n的二维数组,Arr[i*n+j]即是Arr[i][j],计算存储位置的功夫在此应用  
            if(g.edges[i][j]!=0)  
                count++;  
        }  
    g.e=count;  
}  
  
void ArrayToList(int *Arr, int n, ALGraph *&G)  
{  
    int i,j,count=0;  //count用于统计边数,即矩阵中非0元素个数  
    ArcNode *p;  
    G=(ALGraph *)malloc(sizeof(ALGraph));  
    G->n=n;  
    for (i=0; i<n; i++)                 //给邻接表中所有头节点的指针域置初值  
        G->adjlist[i].firstarc=NULL;  
    for (i=0; i<n; i++)                 //检查邻接矩阵中每个元素  
        for (j=n-1; j>=0; j--)  
            if (Arr[i*n+j]!=0)      //存在一条边,将Arr看作n×n的二维数组,Arr[i*n+j]即是Arr[i][j]  
            {  
                p=(ArcNode *)malloc(sizeof(ArcNode));   //创建一个节点*p  
                p->adjvex=j;  
                p->info=Arr[i*n+j];  
                p->nextarc=G->adjlist[i].firstarc;      //采用头插法插入*p  
                G->adjlist[i].firstarc=p;  
            }  
  
    G->e=count;  
}  
  
void MatToList(MGraph g, ALGraph *&G)  
//将邻接矩阵g转换成邻接表G  
{  
    int i,j;  
    ArcNode *p;  
    G=(ALGraph *)malloc(sizeof(ALGraph));  
    for (i=0; i<g.n; i++)                   //给邻接表中所有头节点的指针域置初值  
        G->adjlist[i].firstarc=NULL;  
    for (i=0; i<g.n; i++)                   //检查邻接矩阵中每个元素  
        for (j=g.n-1; j>=0; j--)  
            if (g.edges[i][j]!=0)       //存在一条边  
            {  
                p=(ArcNode *)malloc(sizeof(ArcNode));   //创建一个节点*p  
                p->adjvex=j;  
                p->info=g.edges[i][j];  
                p->nextarc=G->adjlist[i].firstarc;      //采用头插法插入*p  
                G->adjlist[i].firstarc=p;  
            }  
    G->n=g.n;  
    G->e=g.e;  
}  
  
void ListToMat(ALGraph *G,MGraph &g)  
//将邻接表G转换成邻接矩阵g  
{  
    int i,j;  
    ArcNode *p;  
    for (i=0; i<g.n; i++)   //先初始化邻接矩阵  
        for (j=0; j<g.n; j++)  
            g.edges[i][j]=0;  
    for (i=0; i<G->n; i++)  //根据邻接表,为邻接矩阵赋值  
    {  
        p=G->adjlist[i].firstarc;  
        while (p!=NULL)  
        {  
            g.edges[i][p->adjvex]=p->info;  
            p=p->nextarc;  
        }  
    }  
    g.n=G->n;  
    g.e=G->e;  
}  
  
void DispMat(MGraph g)  
//输出邻接矩阵g  
{  
    int i,j;  
    for (i=0; i<g.n; i++)  
    {  
        for (j=0; j<g.n; j++)  
            if (g.edges[i][j]==INF)  
                printf("%3s","∞");  
            else  
                printf("%3d",g.edges[i][j]);  
        printf("\n");  
    }  
}  
  
void DispAdj(ALGraph *G)  
//输出邻接表G  
{  
    int i;  
    ArcNode *p;  
    for (i=0; i<G->n; i++)  
    {  
        p=G->adjlist[i].firstarc;  
        printf("%3d: ",i);  
        while (p!=NULL)  
        {  
            printf("-->%d/%d ",p->adjvex,p->info);  
            p=p->nextarc;  
        }  
        printf("\n");  
    }  
}  
//返回图G中编号为v的顶点的出度  
int OutDegree(ALGraph *G,int v)  
{  
    ArcNode *p;  
    int n=0;  
    p=G->adjlist[v].firstarc;  
    while (p!=NULL)  
    {  
        n++;  
        p=p->nextarc;  
    }  
    return n;  
}  
  
//输出图G中每个顶点的出度  
void OutDs(ALGraph *G)  
{  
    int i;  
    for (i=0; i<G->n; i++)  
        printf("  顶点%d:%d\n",i,OutDegree(G,i));  
}  
  
//输出图G中出度最大的一个顶点  
void OutMaxDs(ALGraph *G)  
{  
    int maxv=0,maxds=0,i,x;  
    for (i=0; i<G->n; i++)  
    {  
        x=OutDegree(G,i);  
        if (x>maxds)  
        {  
            maxds=x;  
            maxv=i;  
        }  
    }  
    printf("顶点%d,出度=%d\n",maxv,maxds);  
}  
//输出图G中出度为0的顶点数  
void ZeroDs(ALGraph *G)  
{  
    int i,x;  
    for (i=0; i<G->n; i++)  
    {  
        x=OutDegree(G,i);  
        if (x==0)  
            printf("%2d",i);  
    }  
    printf("\n");  
}  
  
//返回图G中是否存在边<i,j>  
bool Arc(ALGraph *G, int i,int j)  
{  
    ArcNode *p;  
    bool found = false;  
    p=G->adjlist[i].firstarc;  
    while (p!=NULL)  
    {  
        if(p->adjvex==j)  
        {  
            found = true;  
            break;  
        }  
        p=p->nextarc;  
    }  
    return found;  
}  
#ifndef GRAPH_H_INCLUDED  
#define GRAPH_H_INCLUDED  
  
#define MAXV 100                //最大顶点个数  
#define INF 32767       //INF表示∞  
typedef int InfoType;  
  
//以下定义邻接矩阵类型  
typedef struct  
{  
    int no;                     //顶点编号  
    InfoType info;              //顶点其他信息,在此存放带权图权值  
} VertexType;                   //顶点类型  
  
typedef struct                  //图的定义  
{  
    int edges[MAXV][MAXV];      //邻接矩阵  
    int n,e;                    //顶点数,弧数  
    VertexType vexs[MAXV];      //存放顶点信息  
} MGraph;                       //图的邻接矩阵类型  
  
//以下定义邻接表类型  
typedef struct ANode            //弧的结点结构类型  
{  
    int adjvex;                 //该弧的终点位置  
    struct ANode *nextarc;      //指向下一条弧的指针  
    InfoType info;              //该弧的相关信息,这里用于存放权值  
} ArcNode;  
  
typedef int Vertex;  
  
typedef struct Vnode            //邻接表头结点的类型  
{  
    Vertex data;                //顶点信息  
    int count;                  //存放顶点入度,只在拓扑排序中用  
    ArcNode *firstarc;          //指向第一条弧  
} VNode;  
  
typedef VNode AdjList[MAXV];    //AdjList是邻接表类型  
  
typedef struct  
{  
    AdjList adjlist;            //邻接表  
    int n,e;                    //图中顶点数n和边数e  
} ALGraph;                      //图的邻接表类型  
  
//功能:由一个反映图中顶点邻接关系的二维数组,构造出用邻接矩阵存储的图  
//参数:Arr - 数组名,由于形式参数为二维数组时必须给出每行的元素个数,在此将参数Arr声明为一维数组名(指向int的指针)  
//      n - 矩阵的阶数  
//      g - 要构造出来的邻接矩阵数据结构  
void ArrayToMat(int *Arr, int n, MGraph &g); //用普通数组构造图的邻接矩阵  
void ArrayToList(int *Arr, int n, ALGraph *&); //用普通数组构造图的邻接表  
void MatToList(MGraph g,ALGraph *&G);//将邻接矩阵g转换成邻接表G  
void ListToMat(ALGraph *G,MGraph &g);//将邻接表G转换成邻接矩阵g  
void DispMat(MGraph g);//输出邻接矩阵g  
void DispAdj(ALGraph *G);//输出邻接表G  
int OutDegree(ALGraph *G,int v);  
void OutDs(ALGraph *G);  
void OutMaxDs(ALGraph *G);  
void ZeroDs(ALGraph *G);  
bool Arc(ALGraph *G, int i,int j);  
#endif // GRAPH_H_INCLUDED  

运行结果:


知识点总结:

计算出度即是计算此顶点指向其他顶点的边的条数,用指针的方式去判定此顶点指向的是具体的顶点还是空的。计算每个顶点也是如此。

求最大出度就是在求出每个顶点出度的时候在进行比较


学习心得:

可以以画图帮助理解,搞清楚递归

以下是一个实现旅游路线设计问题的示例代码,使用邻接表存储: ```c #include <stdio.h> #include <stdlib.h> #define MAX_VERTEX_NUM 20 // 最大顶点数 // 边表结点 typedef struct ArcNode{ int adjvex; // 邻接点在顶点数组中的位置下标 struct ArcNode *nextarc;// 指向下一个邻接点的指针 int weight; // 边的权重(景点间距离) }ArcNode; // 顶点表结点 typedef struct VNode{ char data; // 顶点的数据 ArcNode *firstarc; // 指向第一条依附该顶点的边的指针 }VNode, AdjList[MAX_VERTEX_NUM]; // 结构 typedef struct{ AdjList vertices; // 邻接表 int vexnum, arcnum; // 顶点数和边数 }ALGraph; // 创建邻接表存储的无向 void CreateGraph(ALGraph *G, char *vexs, int n, char *edges, int m){ int i, j, k, w; ArcNode *p; G->vexnum = n; G->arcnum = m; // 初始化顶点表 for(i = 0; i < n; i++){ G->vertices[i].data = vexs[i]; G->vertices[i].firstarc = NULL; } // 构造边表 for(k = 0; k < m; k++){ i = edges[k*3] - 'a'; // 边的起点 j = edges[k*3+1] - 'a'; // 边的终点 w = edges[k*3+2] - '0'; // 边的权重(景点间距离) // 添加边(i, j) p = (ArcNode*)malloc(sizeof(ArcNode)); p->adjvex = j; p->weight = w; p->nextarc = G->vertices[i].firstarc; G->vertices[i].firstarc = p; // 添加边(j, i) p = (ArcNode*)malloc(sizeof(ArcNode)); p->adjvex = i; p->weight = w; p->nextarc = G->vertices[j].firstarc; G->vertices[j].firstarc = p; } } // 打印邻接表存储 void PrintGraph(ALGraph G){ int i; ArcNode *p; for(i = 0; i < G.vexnum; i++){ printf("%c:", G.vertices[i].data); p = G.vertices[i].firstarc; while(p != NULL){ printf(" %c(%d)", G.vertices[p->adjvex].data, p->weight); p = p->nextarc; } printf("\n"); } } int main(){ ALGraph G; char vexs[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'}; char edges[] = { 'a', 'b', '2', 'a', 'c', '4', 'a', 'd', '1', 'b', 'e', '3', 'c', 'f', '5', 'd', 'g', '6', 'e', 'h', '7', 'f', 'i', '8', 'g', 'j', '9', 'h', 'k', '10', 'i', 'l', '11', 'j', 'm', '12', 'k', 'n', '13' }; CreateGraph(&G, vexs, 14, edges, 13); PrintGraph(G); return 0; } ``` 以上代码中,CreateGraph函数接收顶点数组和边数组作为参数,通过动态分配内存创建邻接表存储的无向。PrintGraph函数打印邻接表存储
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值