#include<stdio.h>
#include<iostream.h>
#include<list>
#include<strstrea.h>
#include<stdlib.h>
#define MaxVerNum 4
#define MaxVertexNum 4
#include<vector>//vetor是一个容器,存放任意类型的动态的“数组”。
using namespace std;//c++标准程序库中的所有标识符都被定义在一个名为std的namespace中;
int n, m, x, y, i;
list<int>::iterator j;//建立一个迭代器j,读取每一个值,读完以后再指向下一个数据;//list->链表;
vector<list<int> >a;//a[i]储存从i出去的边的集合,即邻接表,c是逆邻接表
vector<pair<int, int> >b;//b[i]储存i点的入度和出度,第一个是入度,第二个数出度
//pair的作用,里面有两个参数。将两个数据组合成一个数据;把每条边集合起来,形成一个图;通过make_pair实现;
typedef struct node{ /*边表结点*/
int adjvex; /*邻接点域*/
struct node * next; /*指向下一个邻接点的指针域*/
}EdgeNode;/*若要表示边上信息,则应增加一个数据域info*/
typedef struct ArcNode{
int adjvex;
ArcNode *nextarc;
//InfoType *info;
}ArcNode;
typedef struct vnode{ /*顶点表结点*/
char vertex [20]; /*顶点域*/
EdgeNode * firstedge;/*边表头指针*/
ArcNode *firstarc;
}VertexNode;
typedef VertexNode AdjList[MaxVerNum]; /*AdjList 是邻接表类型*/
typedef struct {
AdjList adjlist; /*邻接表*/
int n,e; /*顶点数和边数*/
}ALGraph; /*ALGraph 是以邻接表方式存储的图类型*/
//建立一个有向图的邻接表存储的算法如下:
void CreateALGraph(ALGraph *G){/*建立有向图的邻接表存储*/
int i,j,k;
EdgeNode * s;
int n,e;
printf(” \n*************数据结构程序设计***************\n”);
printf(” \n*****************************************\n”);
printf(” \n***************建立邻接链表***************\n”);
printf(“************计算任意顶点的出度和入度***********\n”);
printf(“******************建立逆邻接链表************\n”);
printf(“*****************遍历并输入所有边**************\n”);
printf(“*********************开始执行**********************\n”);
printf(“请输入顶点数和边数(输入格式为:顶点数+空格+边数):\n”);
scanf(“%d%d”,&(G->n),&(G->e));
getchar();/*读入顶点数和边数*/
printf(“请输入顶点信息(输入格式为:V0):\n”);
for (i=0;i<(G->n);i++) /*建立有n 个顶点的顶点表*/
{
getchar();
scanf(“%c”,&(G->adjlist[i].vertex));
getchar();
/*读入顶点信息*/
G->adjlist[i].firstedge=NULL; /*顶点的边表头指针设为空*/
}
printf(“请输入边的信息(输入格式为:i,j):\n”);
for ( k=0;k<(G->e);k++) /*建立边表*/
{
scanf(“%d,%d”,&i,&j); /*读入边的顶点对应序号*/
getchar();
s=(EdgeNode*)malloc(sizeof(EdgeNode)); /*生成新边表结点s*/
s->adjvex=j; /*邻接点序号为j*/
s->next=G->adjlist[i].firstedge; /*将新边表结点s 插入到顶点Vi 的边表头部*/
G->adjlist[i].firstedge=s;
}
}/*CreateALGraph*/
void InvertAdjList(AdjList gin,AdjList gout){
//将有向图的出度邻接表改为按入度建立的逆邻接表;
for(i=1;i<=n;i++)
{
strcpy(
gin[i].vertex,gout[i].vertex);
//gin[i].vertex=gout[i].vertex;
gin[i].firstarc=NULL;
}
for(i=1;i<=n;i++)//邻接表转为逆邻接表
{
ArcNode *p;
p=gout[i].firstarc;//取指向邻接表的指针;
while(p!=NULL)
{
int j;
ArcNode *s;
j=p->adjvex;
s=(ArcNode*)malloc(sizeof(ArcNode));//申请结点空间;
s->adjvex=i;
s->nextarc=gin[j].firstarc;
gin[j].firstarc=s;
p=p->nextarc;
}
}
}
int main(){
ALGraph G;
CreateALGraph(&G);
cout<<(“请输入图的结点个数和边数(输入格式为:结点数+空格+边数):”)<<endl;
cin >> n >> m;//n是点的个数,m是边数,点编号从1开始
a.resize(n+1);//resize->改变元素的数目;
b.resize(n+1, make_pair(0, 0));//利用make_pair赋值;
//建立邻接表,并计算入度和出度
for(i = 0; i < m; ++i){
cout<<(“请输入图的有向边:(输入格式为:x+空格+y)”)<<endl;
cin >> x >> y;//x到y有一条有向边
a[x].push_back(y);//往邻接表添加数据,在尾部加入一个数据;
++b[x].second;//x的出度加1;在pair中通过second,first函数访问元素;
++b[y].first;//y的入度加1;
cout<<x<<“的出度是:”<<b[x].second<<endl;
cout<<y<<“的入度是:”<<b[y].first<<endl;
}
cout<<(“***********图的各个点的出度和入度的统计:************\n”)<<endl;
for(i=0;i<n;i++)
{
cout<<i<<“的入度是:”<<b[i].first<<“\n”<<i<<“的出度是:”<<b[i].second<<endl;
}
//遍历邻接表输出所有的边
cout<<(“****************遍历输出图的所有边:********************\n”)<<endl;
for(i = 0; i < n; ++i)
for(j = a[i].begin(); j != a[i].end(); ++j)cout << i << ‘ ‘ << *j << endl;
return 0;
}