经典代码之图 邻接表转换成邻接矩阵

合集下载

图的邻接矩阵和邻接表相互转换

图的邻接矩阵和邻接表相互转换

图的邻接矩阵和邻接表相互转换图的邻接矩阵存储方法具有如下几个特征:1)无向图的邻接矩阵一定是一个对称矩阵。

2)对于无向图的邻接矩阵的第i 行非零元素的个数正好是第i 个顶点的度()i v TD 。

3)对于有向图,邻接矩阵的第i 行非零元素的个数正好是第i 个顶点的出度()i v OD (或入度()i v ID )。

4)用邻接矩阵方法存储图,很容易确定图中任意两个顶点之间是否有边相连;但是,要确定图中有多少条边,则必须按行、按列对每个元素进行检测,所发费得时间代价大。

邻接表是图的一种顺序存储与链式存储相结合的存储方法。

若无向图中有n 个顶点、e 条边,则它的邻接表需n 个头结点和2e 个表结点。

显然,在边稀疏的情况下,用邻接表表示图比邻接矩阵存储空间。

在无向图的邻接表中,顶点i v 的度恰好是第i 个链表中的结点数,而在有向图中,第i 个链表中结点个数是顶点i v 的出度。

在建立邻接表或邻逆接表时,若输入的顶点信息即为顶点的编号,则建立临接表的时间复杂度是)(e n O +;否则,需要通过查找才能得到顶点在图中位置,则时间复杂度为)*(e n O 。

在邻接表上容易找到任意一顶点的第一个邻接点和下一个邻接点,但要判断任意两个顶点之间是否有边或弧,则需要搜索第i 个或第j 个链表,因此,不及邻接矩阵方便。

邻接矩阵和邻接表相互转换程序代码如下:#include<iostream.h>#define MAX 20//图的邻接表存储表示typedef struct ArcNode{int adjvex; //弧的邻接定点 char info; //邻接点值struct ArcNode *nextarc; //指向下一条弧的指针}ArcNode;typedef struct Vnode{ //节点信息char data;ArcNode *link;}Vnode,AdjList[MAX];typedef struct{AdjList vertices;int vexnum; //节点数int arcnum; //边数}ALGraph;//图的邻接矩阵存储表示typedef struct{int n; //顶点个数char vexs[MAX]; //定点信息int arcs[MAX][MAX]; //边信息矩阵}AdjMatrix;/***_____________________________________________________***///函数名:AdjListToMatrix(AdjList g1,AdjListMatrix &gm,int n)//参数:(传入)AdjList g1图的邻接表,(传入)int n顶点个数,(传出)AdjMatrix gm图的邻接矩阵//功能:把图的邻接表表示转换成图的邻接矩阵表示void AdjListToAdjMatrix(ALGraph gl,AdjMatrix &gm){int i,j,k;ArcNode *p;gm.n=gl.vexnum;for(k=0;k<gl.vexnum;k++)gm.vexs[k]=gl.vertices[k].data;for(i=0;i<MAX;i++)for(j=0;j<MAX;j++)gm.arcs[i][j]=0;for(i=0;i<gl.vexnum;i++){p=gl.vertices[i].link; //取第一个邻接顶点while(p!=NULL){ //取下一个邻接顶点gm.arcs[i][p->adjvex]=1;p=p->nextarc;}}}/***________________________________________________***///函数名:AdjMatrixToAdjListvoid AdjMatrixToAdjList(AdjMatrix gm,ALGraph &gl){int i,j,k,choice;ArcNode *p;k=0;gl.vexnum=gm.n;cout<<"请选择所建立的图形是无向图或是有向图:";cin>>choice;for(i=0;i<gm.n;i++){gl.vertices[i].data=gm.vexs[i];gl.vertices[i].link=NULL;}for(i=0;i<gm.n;i++)for(j=0;j<gm.n;j++)if(gm.arcs[i][j]==1){k++;p=new ArcNode;p->adjvex=j;p->info=gm.vexs[j];p->nextarc=gl.vertices[i].link;gl.vertices[i].link=p;}if(choice==1)k=k/2;gl.arcnum=k;}void CreateAdjList(ALGraph &G){int i,s,d,choice;ArcNode *p;cout<<"请选择所建立的图形是有向图或是无向图:";cin>>choice;cout<<"请输入节点数和边数:"<<endl;cin>>G.vexnum>>G.arcnum;for(i=0;i<G.vexnum;i++){cout<<"第"<<i<<"个节点的信息:";cin>>G.vertices[i].data;G.vertices[i].link=NULL;}if(choice==1){for(i=0;i<2*(G.vexnum);i++){cout<<"边----起点序号,终点序号:";cin>>s>>d;p=new ArcNode;p->adjvex=d;p->info=G.vertices[d].data;p->nextarc=G.vertices[s].link;G.vertices[s].link=p;}}else{for(i=0;i<G.vexnum;i++){cout<<"边----起点序号,终点序号:";cin>>s>>d;p=new ArcNode;p->adjvex=d;p->info=G.vertices[d].data;p->nextarc=G.vertices[s].link;G.vertices[s].link=p;}}}void CreateAdjMatrix(AdjMatrix &M){int i,j,k,choice;cout<<"请输入顶点个数:";cin>>M.n;cout<<"请输入如顶点信息:"<<endl;for(k=0;k<M.n;k++)cin>>M.vexs[k];cout<<"请选择所建立的图形是无向图或是有向图:";cin>>choice;cout<<"请输入边信息:"<<endl;for(i=0;i<M.n;i++)for(j=0;j<M.n;j++)M.arcs[i][j]=0;switch(choice){case 1:{for(k=0;k<M.n;k++){cin>>i>>j;M.arcs[i][j]=M.arcs[j][i]=1;}};break;case 2:{for(k=0;k<M.n;k++){cin>>i>>j;M.arcs[i][j]=1;}};break;}}void OutPutAdjList(ALGraph &G){int i;ArcNode *p;cout<<"图的邻接表如下:"<<endl;for(i=0;i<G.vexnum;i++){cout<<G.vertices[i].data;p=G.vertices[i].link;while(p!=NULL){cout<<"---->("<<p->adjvex<<" "<<p->info<<")";p=p->nextarc;}cout<<endl;}}void OutPutAdjMatrix(AdjMatrix gm){cout<<"图的邻接矩阵如下:"<<endl;for(int i=0;i<gm.n;i++){。

有向图的邻接矩阵

有向图的邻接矩阵

有向图的邻接矩阵有向图的邻接矩阵设有向图,,。

令为邻接到的边的条数,称为D的邻接矩阵,记作。

为图7.12的邻接矩阵,不难看出:(1)(即第i行元素之和为的出度),。

(2)(即第j列元素之和为的入度),。

(3)由(1),(2)可知,为D中边的总数,也可看成是D中长度为1的通路总数,而为D中环的个数,即D中长度为1的回路总数。

D中长度大于等于2的通路数和回路数应如何计算呢,为此,先讨论长度等于2的通路数和回路数。

在图D中,从顶点到顶点的长度等于2的通路,中间必经过一顶点。

对于任意的k,若有通路,必有且,即。

反之,若D中不存在通路,必有或,即。

于是在图D中从顶点到顶点的长度等于2的通路数为:由矩阵的乘法规则知,正好是矩阵中的第i行与第j列元素,记,即就是从顶点到顶点的长度等于2的通路数,时,表示从顶点到顶点的长度等于2的回路数。

因此,即矩阵中所有元素的和为长度等于2的通路总数(含回路),其中对角线的元素和为长度等于2的回路总数。

根据以上分析,则有下面的推论。

定义有向图,,D中长度为的通路数和回路数可以用矩阵(简记)来表示,这里,其中,即则为顶点到顶点长度为的通路数,为到自身长度为的回路数。

中所有元素之和为D中长度为的通路数,而中对角线上元素之和为D中始于(终于)各顶点的长度为的回路数。

在图7.12中,计算,,如下:观察各矩阵发现,,,。

于是,D中到长度为,2的通路有3条,长度为3的通路有4条,长度为4的通路有6条。

由,可知,D中到自身长度为的回路各有1条(此时回路为复杂的)。

由于,所以D中长度为2的通路总数为10,其中有3条回路。

从上述分析,可得下面定理。

定理7.5 设为有向图D的邻接矩阵,,则中元素为到长度为的通路数,为D中长度为的通路总数,其中为D中长度为的回路总数。

若再令矩阵,,……,上面定理有下面推论。

推论设,则中元素为D中到长度小于等于的通路数,为D中长度小于等于的通路总数,其中为D中长度小于等于的回路总数。

中国石油大学期末考试复习题 070109数据结构-18

中国石油大学期末考试复习题 070109数据结构-18

《数据结构》综合复习资料一、填空题1、数据结构是()。

2、数据结构的四种基本形式为集合、()、()和()。

3、线性结构的基本特征是:若至少含有一个结点,则除起始结点没有直接前驱外,其他结点有且仅有一个直接();除终端结点没有直接()外,其它结点有且仅有一个直接()。

4、堆栈的特点是(),队列的特点是(),字符串中的数据元素为()。

5、字符串s1=“I am a student!”(单词与单词之间一个空格),s2=“student”,则字符串s1的长度为(),串s2是串s1的一个()串,串s2在s1中的位置为()。

6、KMP算法的特点:效率较();()回溯,对主串仅需要从头到尾扫描()遍,可以边读入边匹配。

7、广义表((a),((b),c),(((d))))的长度为(),表头为(),表尾为()。

8、ADT称为抽象数据类型,它是指()。

9、求下列程序的时间复杂度,并用大O表示方法表示()。

for( i=1 ; i<=n ; + + i)for( j=1 ; j<=i; + + j ){ ++x;a[i][j] = x;}10、以下运算实现在链栈上的退栈操作,请在_____处用适当句子予以填充。

int Pop(LstackTp *ls,DataType *x){ LstackTp *p;if(ls!=NULL){ p=ls;*x= ;ls= ;;return(1);}else return(0);}11、用堆栈求中缀表达式a+b*c/d+e*f的后缀表达式,求出的后缀表达式为()。

12、C语言中存储数组是采用以()为主序存储的,在C语言中定义二维数组float a[8][10],每个数据元素占4个字节,则数组共占用()字节的内存。

若第一个数据元素的存储地址为8000,则a[5][8]的存储地址为()。

13、含零个字符的串称为()串,用 表示。

其他串称为()串。

任何串中所含字符的个数称为该串的()。

图基本算法图的表示方法邻接矩阵邻接表

图基本算法图的表示方法邻接矩阵邻接表

图基本算法图的表⽰⽅法邻接矩阵邻接表 要表⽰⼀个图G=(V,E),有两种标准的表⽰⽅法,即邻接表和邻接矩阵。

这两种表⽰法既可⽤于有向图,也可⽤于⽆向图。

通常采⽤邻接表表⽰法,因为⽤这种⽅法表⽰稀疏图(图中边数远⼩于点个数)⽐较紧凑。

但当遇到稠密图(|E|接近于|V|^2)或必须很快判别两个给定顶点⼿否存在连接边时,通常采⽤邻接矩阵表⽰法,例如求最短路径算法中,就采⽤邻接矩阵表⽰。

图G=<V,E>的邻接表表⽰是由⼀个包含|V|个列表的数组Adj所组成,其中每个列表对应于V中的⼀个顶点。

对于每⼀个u∈V,邻接表Adj[u]包含所有满⾜条件(u,v)∈E的顶点v。

亦即,Adj[u]包含图G中所有和顶点u相邻的顶点。

每个邻接表中的顶点⼀般以任意顺序存储。

如果G是⼀个有向图,则所有邻接表的长度之和为|E|,这是因为⼀条形如(u,v)的边是通过让v出现在Adj[u]中来表⽰的。

如果G是⼀个⽆向图,则所有邻接表的长度之和为2|E|,因为如果(u,v)是⼀条⽆向边,那么u会出现在v的邻接表中,反之亦然。

邻接表需要的存储空间为O(V+E)。

邻接表稍作变动,即可⽤来表⽰加权图,即每条边都有着相应权值的图,权值通常由加权函数w:E→R给出。

例如,设G=<V,E>是⼀个加权函数为w的加权图。

对每⼀条边(u,v)∈E,权值w(u,v)和顶点v⼀起存储在u的邻接表中。

邻接表C++实现:1 #include <iostream>2 #include <cstdio>3using namespace std;45#define maxn 100 //最⼤顶点个数6int n, m; //顶点数,边数78struct arcnode //边结点9 {10int vertex; //与表头结点相邻的顶点编号11int weight = 0; //连接两顶点的边的权值12 arcnode * next; //指向下⼀相邻接点13 arcnode() {}14 arcnode(int v,int w):vertex(v),weight(w),next(NULL) {}15 arcnode(int v):vertex(v),next(NULL) {}16 };1718struct vernode //顶点结点,为每⼀条邻接表的表头结点19 {20int vex; //当前定点编号21 arcnode * firarc; //与该顶点相连的第⼀个顶点组成的边22 }Ver[maxn];2324void Init() //建⽴图的邻接表需要先初始化,建⽴顶点结点25 {26for(int i = 1; i <= n; i++)27 {28 Ver[i].vex = i;29 Ver[i].firarc = NULL;30 }31 }3233void Insert(int a, int b, int w) //尾插法,插⼊以a为起点,b为终点,权为w的边,效率不如头插,但是可以去重边34 {35 arcnode * q = new arcnode(b, w);36if(Ver[a].firarc == NULL)37 Ver[a].firarc = q;38else39 {40 arcnode * p = Ver[a].firarc;41if(p->vertex == b) //如果不要去重边,去掉这⼀段42 {43if(p->weight < w)44 p->weight = w;45return ;46 }47while(p->next != NULL)48 {49if(p->next->vertex == b) //如果不要去重边,去掉这⼀段50 {51if(p->next->weight < w);52 p->next->weight = w;53return ;54 }55 p = p->next;56 }57 p->next = q;58 }59 }60void Insert2(int a, int b, int w) //头插法,效率更⾼,但不能去重边61 {62 arcnode * q = new arcnode(b, w);63if(Ver[a].firarc == NULL)64 Ver[a].firarc = q;65else66 {67 arcnode * p = Ver[a].firarc;68 q->next = p;69 Ver[a].firarc = q;70 }71 }7273void Insert(int a, int b) //尾插法,插⼊以a为起点,b为终点,⽆权的边,效率不如头插,但是可以去重边74 {75 arcnode * q = new arcnode(b);76if(Ver[a].firarc == NULL)77 Ver[a].firarc = q;78else79 {80 arcnode * p = Ver[a].firarc;81if(p->vertex == b) return; //去重边,如果不要去重边,去掉这⼀句82while(p->next != NULL)83 {84if(p->next->vertex == b) //去重边,如果不要去重边,去掉这⼀句85return;86 p = p->next;87 }88 p->next = q;89 }90 }91void Insert2(int a, int b) //头插法,效率跟⾼,但不能去重边92 {93 arcnode * q = new arcnode(b);94if(Ver[a].firarc == NULL)95 Ver[a].firarc = q;96else97 {98 arcnode * p = Ver[a].firarc;99 q->next = p;100 Ver[a].firarc = q;101 }102 }103void Delete(int a, int b) //删除以a为起点,b为终点的边104 {105 arcnode * p = Ver[a].firarc;106if(p->vertex == b)107 {108 Ver[a].firarc = p->next;109 delete p;110return ;111 }112while(p->next != NULL)113if(p->next->vertex == b)114 {115 p->next = p->next->next;116 delete p->next;117return ;118 }119 }120121void Show() //打印图的邻接表(有权值)122 {123for(int i = 1; i <= n; i++)124 {125 cout << Ver[i].vex;126 arcnode * p = Ver[i].firarc;127while(p != NULL)128 {129 cout << "->(" << p->vertex << "," << p->weight << ")";130 p = p->next;131 }132 cout << "->NULL" << endl;133 }134 }135136void Show2() //打印图的邻接表(⽆权值)137 {138for(int i = 1; i <= n; i++)140 cout << Ver[i].vex;141 arcnode * p = Ver[i].firarc;142while(p != NULL)143 {144 cout << "->" << p->vertex;145 p = p->next;146 }147 cout << "->NULL" << endl;148 }149 }150int main()151 {152int a, b, w;153 cout << "Enter n and m:";154 cin >> n >> m;155 Init();156while(m--)157 {158 cin >> a >> b >> w; //输⼊起点、终点159 Insert(a, b, w); //插⼊操作160 Insert(b, a, w); //如果是⽆向图还需要反向插⼊161 }162 Show();163return0;164 }View Code 邻接表表⽰法也有潜在的不⾜之处,即如果要确定图中边(u,v)是否存在,只能在顶点u邻接表Adj[u]中搜索v,除此之外没有其他更快的办法。

邻接矩阵和度矩阵的公式

邻接矩阵和度矩阵的公式

邻接矩阵和度矩阵的公式邻接矩阵和度矩阵是图论中常用的两种表示图的方式,它们可以帮助我们更方便地分析和研究图的性质和特征。

邻接矩阵指的是通过矩阵来表示图的边和节点之间的关系,而度矩阵则是表示节点的度数情况的矩阵。

下面我们就来详细讲解这两种矩阵的公式和用法。

一、邻接矩阵邻接矩阵是一种方阵,从第i行第j列到第j行第i列也具有相同的值,表示了节点之间的邻接关系。

主要公式如下:1. 无向图对于一个n个节点的无向图来说,邻接矩阵的元素a[i][j]表示的是节点i和节点j之间是否存在边,其中0表示没有边,1表示有边。

由于是无向图,所以矩阵的上下三角是对称的。

下面是一个无向图的邻接矩阵示例:```0 1 1 01 0 1 01 1 0 10 0 1 0```2. 有向图对于一个n个节点的有向图来说,邻接矩阵的元素a[i][j]表示的是节点i到节点j是否存在有向边,其中0表示没有有向边,1表示有有向边。

下面是一个有向图的邻接矩阵示例:```0 1 0 00 0 1 01 0 0 10 0 1 0```邻接矩阵的优点是方便且易于理解,可以用于表示不同类型的图。

但是在稀疏图中会存在大量的0元素,浪费空间,此时可以使用邻接表优化。

二、度矩阵度矩阵是一个n维的矩阵,表示每个节点的度数情况。

主要公式如下:1. 无向图对于无向图来说,每个节点的度数等于该节点所连的所有边的数量。

度矩阵的第i个对角线元素d[i][i]表示节点i的度数。

下面是一个无向图的度矩阵示例:```2 0 0 00 2 0 00 0 3 00 0 0 1```2. 有向图对于有向图来说,每个节点的入度和出度可以分别计算。

入度是指以节点i为终点的边的数量,出度是指以节点i为起点的边的数量。

度矩阵的第i个对角线元素d[i][i]表示节点i的总度数,即入度与出度之和。

下面是一个有向图的度矩阵示例:```2 1 0 00 0 1 01 0 1 10 1 0 0```度矩阵的优点是可以方便地计算得到每个节点的度数情况,可以用于分析图的特性和性质,如连通性、欧拉图等。

邻接矩阵的应用1

邻接矩阵的应用1
3
3.1
定义 :设 是图 的结点,则称矩阵 为 的邻接矩阵,其中, 是使 邻接的边的条数 并且 是环时, ,否则 .
例如
则上图的邻接矩阵为:
再如:
它的邻接矩阵为:
3.
性质1 对角线元素全为0当且仅当图 没有环.此时 是对称矩阵.
性质2 在没有环的图中, 等于对应行或列中1的个数.
性质3 的第 行(或第 列)元素之和为结点 的度数 .
欧拉对于一般的图提出了一个普遍的判别法则:要从图中一点出发,经过所有的边一次且仅一次,能回到原来的出发点,则这个图必须是连通的,且每个点都必须与偶数条边相关联.显然,图(1)中的各点都是连通的,但每个点都不是与偶数条边相连接,因此七桥问题不可能有解.1845年,德国物理学家G.R.基尔霍夫为了解决一类线性联立方程组而创建“树”理论.他把电网络和其中的电阻、电容和电感等抽象化,用一个只有点和边组成的组合结构来代替电网络,而不指明每条边所代表的电器元件种类,这样就可以方便地对方程组进行求解 .1852年F.格思里在对地图着色时发现,无论多么复杂的地图,只要用四种颜色就能将相邻区域区分开来。这就是所谓“四色猜想” 经过百余年的努力,直到1976年才由K.阿佩尔和W.赫肯借助电子计算机证明了四色定理.1856年,W.R.哈密顿在给 R.L.格雷夫斯的信中提出一个游戏:用正十二面体上20个顶点表示20个城市,要求游戏者沿着各边行走,走遍每个城市一次且仅一次,最后回到原出发城市。这个游戏促使人们研究如何判断一个图有无这一性质,如果有,则又如何确定这样的路径。这是一个至今尚未完全解决的问题.
深度优先遍历 ,假设初始态是图中所有顶点未曾被访问,从图中某个顶点 出发,访问此顶点,然后依次从 的未被访问的邻接点出发深度优先遍历图,直至图中所有和 有路径相通的顶点都被访问到;若此时图中还有未被访问的顶点,则从一个未被访问的顶点开始,重复上述过程,直至图中所有顶点都被访问为止.显然,这是一个复杂的递归过程 .

邻接矩阵-南京大学

邻接矩阵-南京大学
v1 v2
v4
v3
0 0 A(G) 1 1
1 0 0 0 1 1 1 0 1 0 0 0
可推广到简单无向图
举例(邻接矩阵)
v1 v2
v4
v3
0 1 A(G) 1 1
1 0 1 0
1 1 0 1
1 0 1 0
简单无向图的邻接矩阵是对称矩阵
邻接矩阵(adjacency matrix)

简单有向图G = (V, E, ) ,设V=v1,…,vn,E= e1,…,em。

A(G)=aij称为G的邻接矩阵(n×n 阶矩阵),其中
1 如果v i邻接到v j a ij 0 否则
eE. (e)=(vi, vj)
举例(邻接矩阵)
邻接矩阵的运算

逆图(转置矩阵)

设G的邻接矩阵为 A ,则 G 的逆图的邻接矩阵是 A 的转 置矩阵,用AT表示。
0100 0011 A 1101 1000
0011 1010 T A 0100 0110
邻接矩阵的运算
邻接矩阵的运算

顶点的度


行中1的个数就是行中相应结点的出度
列中1的个数就是列中相应结点的入度
v1
v2
v4
v3
Hale Waihona Puke 0 0 A 1 11 0 0 0 1 1 1 0 1 0 0 0
Deg+(1)=1,Deg-(1)=2
Deg+(2)=2,Deg-(2)=2
Deg+(3)=3,Deg-(3)=1 Deg+(4)=1,Deg-(4)=2
邻接表

邻接矩阵的算法

邻接矩阵的算法

#include"邻接矩阵.h"//图的邻接矩阵存储的初始化算法void InitMatrix(adjmatrix GA,int k){int i,j;for(i=0;i<MaxVertexNum;i++)for(j=0;j<MaxVertexNum;j++)if(i==j) GA[i][j]=0;else if(k) GA[i][j]=MaxValue;else GA[i][j]=0;}//根据一个图的边集生成图的邻接矩阵的算法void CreateMatrix(adjmatrix GA,int n,char*s,int k1,int k2)//k1为0则为无向图否则为有向图,k2为0则为无权图否则为有权图//s字符串用来保存一个图的边集,n为图的顶点数{istrstream sin(s);//定义sin为字符串输入流,与s边集对应char c1,c2,c3;//用来保存从输入流读入的字符int i,j;//WeightType w;//sin>>c1;//if(k1==0&&k2==0)//建立无向无权图do{//从sin流(即字符串s)中读入和处理一条边sin>>c1>>i>>c2>>j>>c3;//依次读入一条边的5个数据GA[i][j]=GA[j][i]=1;//置相应的对称元素为1sin>>c1;//读入逗号成右花括号if(c1=='}') break;//编辑处理完毕,退出循环}while(1);else if(k1==0&&k2!=0)//建立无向有权图do{sin>>c1>>i>>c2>>j>>c3;GA[i][j]=GA[j][i]=w;//置相应的对称元素为wsin>>c1;if(c1==')') break;}while(1);else if(k1==0&&k2!=0)//建立有向无权图do{sin>>c1>>i>>c2>>j>>c3;GA[i][j]=1;//置相应的元素为1sin>>c1;if(c1==')') break;}while(1);else if(k1==0&&k2!=0)//建立有向有权图do{sin>>c1>>i>>c2>>j>>c3;GA[i][j]=w;//置相应的元素为wsin>>c1;if(c1=='}') break;}while(1);}int Degree(adjmatrix GA,int numb)//度数{int i,d=0;for(i=0;i<MaxVertexNum;i++){if(GA[numb][i]!=0 && GA[numb][i]!=MaxValue)d++;}return d;}//输出用邻接矩阵表示一个图的顶点集和边集void PrintMatrix(adjmatrix GA,int n,int k1,int k2){int i,j;cout<<"V={";//输出顶点集开始for(i=0;i<n;i++)cout<<i<<',';//输出顶点集结束cout<<'}'<<endl;cout<<"E=(";//输出边集开始if(k2==0)//对无权图的处理情况{for(i=0;i<n;i++)for(j=0;j<n;j++)if(GA[i][j]==1)if(k1==0)//对无向无权图的处理{if(i<j)//避免输出重复边cout<<'('<<i<<','<<j<<')'<<',';}else //对有向无权图的处理cout<<'<'<<i<<','<<j<<'>'<<',';}else{//对有权图的处理情况for(i=0;i<n;i++)for(j=0;i<n;j++)if(GA[i][j]!=0&&GA[i][j]!=MaxValue)if(k1==0)//的对无向有权图的处理{if(i<j)cout<<'('<<i<<','<<j<<')'<<GA[i][j]<<',';}else //对有向有权图的处理cout<<'<'<<i<<','<<j<<'>'<<GA[i][j]<<',';}cout<<'}'<<endl;}//按图的邻接矩阵输出图的深度优先遍历序列void dfsMatrix(adjmatrix GA,int i,int n,bool*visited){cout<<i<<' ';visited[i]=true;for(int j=0;j<n;j++)if(GA[i][j]!=0&&GA[i][j]!=MaxValue&&!visited[j])dfsMatrix(GA,j,n,visited);}//按图的邻接矩阵输出图的广度优先遍历序列void bfsMatrix(adjmatrix GA,int i,int n,bool*visited){const int MaxSize=30;int q[MaxSize]={0};int front=0,rear=0;cout<<i<<' ';visited[i]=true;q[++rear]=i;while(front!=rear){front=(front+1)%MaxSize;int k=q[front];for(int j=0;j<n;j++){if(GA[k][j]!=0&&GA[k][j]!=MaxValue&&!visited[j]){cout<<j<<' ';visited[j]=true;rear=(rear+1)%MaxSize;q[rear]=j;}}}}void main(){int i,n,k1,k2;cout<<"输入待处理图的定点数:";cin>>n;cout<<"输入图的有无向和有无权选择(0为无,非0为有):";cin>>k1>>k2;bool* visited=new bool[n];adjmatrix ga;InitMatrix(ga,k2);cout<<"输入图的边集:";char*a=new char[100];cin>>a;CreateMatrix(ga,n,a,k1,k2);cout<<"按图的邻接矩阵得到的深度优先遍历序列:"<<endl;for(i=0;i<n;i++)visited[i]=false;dfsMatrix(ga,0,n,visited);cout<<endl;cout<<"按图的邻接矩阵得到的广度优先遍历序列:"<< endl;for(i=0;i<n;i++) visited[i]=false;bfsMatrix(ga,0,n,visited);cout<<endl;cout<<"度数为:"<<Degree(ga,n)<<endl;;PrintMatrix(ga,n,k1,k2);}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

运行结果是:
请输入节点数和弧数:3 3
第1 个节点信息:5
第2 个节点信息:6
第3 个节点信息:7
第1 条弧的弧尾和弧头的位置:1 2 第2 条弧的弧尾和弧头的位置:2 3 第3 条弧的弧尾和弧头的位置:1 3 图的邻接表表示为:
[1,5]-->[3,7]-->[2,6]-->^
[2,6]-->[3,7]-->[1,5]-->^
[3,7]-->[1,5]-->[2,6]-->^
交换后是::
图的邻接矩阵表示为:
0 1 1
1 0 1
1 1 0
请按任意键继续. . .
代码是:
#include<stdio.h>
#include<stdlib.h>
#define MAXV 100
typedef struct
{
int no;
int info;
}vertextype;
typedef struct
{
int num;
int edges[MAXV][MAXV];
// vertextype vexs[MAXV];
}mgraph;
struct arcnode
{
int adjvex;
int info;
struct arcnode *nextarc;
};
struct vexnode
{
int data;
struct arcnode *firstarc;
};
struct graph
{
int vexnum,arcnum;
vexnode vexpex[100];
};
struct graph *creatgraph()
{
int i,s,d;
struct graph *g;
struct arcnode *p,*q;
g = (struct graph *)malloc(sizeof(struct graph));
printf("请输入节点数和弧数:");
scanf("%d%d", &g->vexnum, &g->arcnum);
for(i=1; i<=g->vexnum; i++)
{
printf("第%d 个节点信息:",i);
scanf("%d", &g->vexpex[i].data);
g->vexpex[i].firstarc = NULL;
}
for(i=1; i<=g->arcnum; i++)
{
p = (struct arcnode *)malloc(sizeof(struct arcnode));
q = (struct arcnode *)malloc(sizeof(struct arcnode));
printf("第%d 条弧的弧尾和弧头的位置:",i);
scanf("%d%d",&s,&d);
p->adjvex = d;
p->info = g->vexpex[d].data;
p->nextarc = g->vexpex[s].firstarc;
g->vexpex[s].firstarc = p;
q->adjvex = s;
q->info = g->vexpex[s].data;
q->nextarc = g->vexpex[d].firstarc;
g->vexpex[d].firstarc = q;
}
return g; //return graph!
}
void changeto(graph *G, mgraph &g)
{
int i,j;
arcnode *m;
g.num = G->vexnum;
for(i = 1; i<=G->vexnum; i++)
for(j = 1; j<=G->vexnum; j++)
g.edges[i][j] = 0;
for(i = 1; i<=G->vexnum; i++)
{
m = G->vexpex[i].firstarc;
while(m)
{
g.edges[i][m->adjvex] = 1;
m = m->nextarc;
}
}
}
void printtu(struct graph *g,int n)
{
int i;
arcnode *p;
printf("图的邻接表表示为:\n");
for(i=1; i<=n; i++)
{
printf(" [%d,%d]-->", i, g->vexpex[i].data);
p = g->vexpex[i].firstarc;
while(p != NULL)
{
printf("[%d,%d]-->", p->adjvex, p->info);
p = p->nextarc;
}
printf("^\n");
}
}
void printftu2(mgraph g)
{
int i,j;
printf("图的邻接矩阵表示为:\n");
for(i = 1; i<=g.num; i++)
{
for(j = 1;j <= g.num; j++)
printf("%d ",g.edges[i][j]);
printf("\n");
}
}
void main()
{
graph *G;
mgraph g;
G = creatgraph();
printtu(G,G->vexnum);
printf("交换后是::\n");
changeto(G, g);
printftu2(g);
system("PAUSE");
}。

相关文档
最新文档