/**
* 创造函数的入口函数
* @param G
* @return
*/intCreatGraph_AL(ALGraph* G){printf("Please input the kind of G:");scanf("%d",&G->kind);switch(G->kind){case DG:returnCreatDG_AL(G);case UDG:returnCreatUDG_AL(G);default:break;}return1;}
三:构造有向图
//创建有向图intCreatDG_AL(ALGraph* G){
ArcNode* r[MAX_VERTEX_NUM];//用作访问标记,用来定位
ArcNode* p;//需要插入的结点printf("Please input the num of vex and arc:");scanf("%d,%d",&(G->vexnum),&(G->arcnum));getchar();//初始化数据printf("Please input the data of vex:\n");for(int i =0; i < G->vexnum;++i){scanf("%d",&(G->vertices[i].data));getchar();
G->vertices[i].firstarc =NULL;
r[i]=NULL;}int v1,v2;//读取各边,开始制作邻接表for(int i =0; i < G->arcnum;++i){printf("Please input the trail and head:");scanf("%d,%d",&v1,&v2);getchar();//这里的头和尾指的是,弧头的顶点和弧尾的顶点int trail =LocateVex_AL(*G,v1);int head =LocateVex_AL(*G,v2);//判断图中是否含有顶点if(head==-1||trail==-1){return0;}//制作结点
p =(ArcNode*)malloc(sizeof(ArcNode));if(!p){exit(0);//分配内存失败}
p->adjvex = head;
p->nextarc =NULL;if(r[trail]==NULL){
G->vertices[trail].firstarc = p;}else{
r[trail]->nextarc = p;}
r[trail]= p;}return1;}
四:构造无向图
//创建无向图intCreatUDG_AL(ALGraph* G){
ArcNode* r[MAX_VERTEX_NUM];
ArcNode* p;
ArcNode* q;printf("Please input the num of vex and arc:");scanf("%d,%d",&(G->vexnum),&(G->arcnum));getchar();//初始化for(int i =0; i < G->vexnum;++i){printf("Please input the data of vex:");scanf("%d,%d",&(G->vertices[i].data));getchar();
G->vertices [i].firstarc =NULL;
r[i]=NULL;}int v1,v2;for(int i =0; i < G->arcnum;++i){printf("Please input the trail and head:");scanf("%d,%d",&v1,&v2);getchar();//在无向图中就没有严格的弧的头尾概念,这里只是做一个区别而已int trail =LocateVex_AL(*G,v1);int head =LocateVex_AL(*G,v2);if(head ==-1|| trail ==-1){return0;}//制作结点
p =(ArcNode*)malloc(sizeof(ArcNode));if(!p){exit(0);}
p->adjvex = head;
p->nextarc =NULL;if(r[trail]==NULL){
G->vertices[trail].firstarc = p;}else{
r[trail]->nextarc = p;}
r[trail]= p;
q =(ArcNode*)malloc(sizeof(ArcNode));if(!q){exit(0);}
q->adjvex = trail;
q->nextarc =NULL;if(r[head]==NULL){
G->vertices[head].firstarc = q;}else{
r[head]->nextarc = q;}
r[head]= q;}return1;}
五:获取顶点在数组中的下标
/**
* 定位顶点在顶点数组中的位置,返回下标
* @param G
* @param v
* @return 返回顶点在顶点数组中位置,下标,否则返回-1
*/intLocateVex_AL(ALGraph G,VetexType_Al v){for(int i =0; i < G.vexnum;++i){if(G.vertices[i].data == v){return i;}}return-1;}
六:获取指定结点的第一个相邻顶点的下标值
/**
* 获取与给定顶点的第一个相邻顶点在顶点数组中的下标
* @param G
* @param v
* @return 返回顶点在顶点数组中的下标
*/intFirstAdjVex_AL(ALGraph G,VetexType_Al v){int index =LocateVex_AL(G,v);if(index!=-1&& G.vertices[index].firstarc){return G.vertices[index].firstarc->adjvex;}return-1;}
七:获取顶点v相对顶点w的下一个顶点的下标值
/**
* 获取顶点v相对于顶点w的下一个邻接顶点,返回顶点在顶点数组中下标
* @param G
* @param v
* @param w
* @return
*/intNextAdjVex_AL(ALGraph G,VetexType_Al v,VetexType_Al w){int indexv =LocateVex_AL(G,v);int indexw =LocateVex_AL(G,w);
ArcNode* p;//用来循环的指针if(indexv!=-1&& indexw!=-1&& G.vertices[indexv].firstarc){
p = G.vertices[indexv].firstarc;while(p){if(p->adjvex == indexw){if(p->nextarc){return p->nextarc->adjvex;}else{return-1;}}else{
p = p->nextarc;}}}else{return-1;}return-1;}
八:深度优先遍历算法
/**
*使用邻接表和邻接矩阵表示的图,深度优先遍历的算法基本上没有改变,只是需要注意对于顶点数据的表示
*/voidvisitVexAL(ALGraph G,int index){printf("%d\t",G.vertices[index].data);}//全局变量
bool visited[MAX_VERTEX_NUM];//深度优先遍历算法voidDFSTraverse_AL(ALGraph G){//初始化访问变量for(int i =0; i < G.vexnum;++i){
visited[i]= false;}for(int i =0; i < G.vexnum;++i){if(!visited[i]){//没有被访问DFS_AL(G,i);}}}//深度优先遍历核心算法voidDFS_AL(ALGraph G,int indexv){
visited[indexv]= true;visitVexAL(G,indexv);int w;//递归for(w =FirstAdjVex_AL(G,G.vertices[indexv].data);w>=0;
w =NextAdjVex_AL(G,G.vertices[indexv].data,G.vertices[w].data)){if(!visited[w]){DFS_AL(G,w);}}}
九:广度优先遍历算法
/**
* 广度优先遍历,使用数组来模拟队列的操作
* 类似于二叉树的层次遍历
* 邻接矩阵和邻接表的广度优先遍历算法基本一样,同样也只是需要注意对于顶点数据的表示
* @param G
*/voidBFSTraverse_AL(ALGraph G){//对访问标志数组进行初始化操作for(int i =0; i < G.vexnum;++i){
visited[i]= false;}//用数组来模拟队列
VetexType_Al queue[20];int top =0;//头int rear =0;//尾for(int i =0; i < G.vexnum;++i){if(!visited[i]){//如果没有别访问
visited[i]= true;visitVexAL(G,i);//访问//进队列中
queue[rear]= G.vertices[i].data;
rear =(rear+1)%20;while(rear-top !=0){//队列非空时
VetexType_Al v = queue[top];
top =(top+1)%20;for(int w =FirstAdjVex_AL(G,v); w >=0; w =NextAdjVex_AL(G,v,G.vertices[w].data)){if(!visited[w]){
visited[w]= true;visitVexAL(G,w);
queue[rear]= G.vertices[w].data;
rear =(rear+1)%20;}}}}}}