#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define ERROR 0
#define OVERFLOW 0
#define OK 1
#define INFINITY 65535
#define MAX_VERTEX_NUM 20
#define MAX_INFO 20
typedef int Status;
typedef int VRType;
typedef char InfoType;
typedef int VertexType;
typedef enum {DG,DN,UDG,UDN} GraphKind;
typedef struct {
VRType adj;
InfoType *info;
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct {
VertexType vexs[MAX_VERTEX_NUM];
AdjMatrix arcs;
int vexnum;
int arcnum;
GraphKind kind;
}MGraph;
int LocateVex(MGraph G,VertexType v) {
for(int i = 0;i < G.vexnum; i++){
if(G.vexs[i] == v){
return i;
}
}
return -1;
}
Status CreateUDG(MGraph &G) {
int i,j,k,infoflag,len;
char c;
char str[MAX_INFO];
char *info;
VertexType v1,v2;
len = 0;
printf("请分别输入 顶点数量、边的数量、边是否携带信息(要携带输入1否则输入0)\n");
scanf("%d%d%d",&G.vexnum,&G.arcnum,&infoflag);
printf("依次输入顶点(用-1表示顶点 V1 依此类推)\n");
for(i = 0;i < G.vexnum ; i++)
scanf("%d",&G.vexs[i]);
for(i = 0; i < G.vexnum; i++)
for(j = 0;j < G.vexnum ; j++) {
G.arcs[i][j].adj = 0;
G.arcs[i][j].info = NULL;
}
printf("图中有%d条边\n",G.arcnum);
if(G.arcnum>0){
printf("请依次输入这些边(用两个顶点表示一条边)及其权值\n\n\n");
}
for(k = 0; k < G.arcnum; k++) {
scanf("%d%d",&v1,&v2);
printf("%d条边输入完成\n\n\n",k+1);
i = LocateVex(G,v1);
j = LocateVex(G,v2);
if(i >= 0 && j >= 0)
G.arcs[i][j].adj = G.arcs[j][i].adj = 1;
if(infoflag) {
printf("please enter the info:");
while( (c = getchar()) != '#')
str[len++] = c;
info = (char *) malloc(len * sizeof(char));
str[len] = '\0';
strcpy(info,str);
G.arcs[i][j].info = G.arcs[j][i].info = info;
}
}
G.kind = UDG;
return OK;
}
Status CreateDG(MGraph &G) {
int i,j,k,len,infoflag;
VertexType v1,v2;
char str[MAX_INFO];
char *info;
char c;
printf("请分别输入 顶点数量、弧的数量、弧是否携带信息(要携带输入1否则输入0)\n");
scanf("%d%d%d",&G.vexnum,&G.arcnum,&infoflag);
printf("依次输入顶点(用-1表示顶点 V1 依此类推)\n");
for(i = 0;i < G.vexnum ; i++)
scanf("%d",&G.vexs[i]);
for(i = 0; i < G.vexnum; i++)
for(j = 0;j < G.vexnum ; j++) {
G.arcs[i][j].adj = 0;
G.arcs[i][j].info = NULL;
}
printf("图中有%d条弧\n",G.arcnum);
if(G.arcnum>0){
printf("请依次输入这些弧(用两个顶点表示一条弧)及其权值\n\n\n");
}
for(k = 0; k < G.arcnum; k++) {
scanf("%d%d",&v1,&v2);
printf("%d条弧输入完成\n\n\n",k+1);
i = LocateVex(G,v1);
j = LocateVex(G,v2);
if(i >= 0 && j >= 0)
G.arcs[i][j].adj = 1;
if(infoflag) {
printf("please enter the info:");
while( (c = getchar()) != '#')
str[len++] = c;
info = (char *) malloc(len * sizeof(char));
strcpy(info,str);
G.arcs[i][j].info = info;
}
}
G.kind = DG;
return OK;
}
Status CreateDN(MGraph &G) {
int i,j,k,len,infoflag,w;
VertexType v1,v2;
char str[MAX_INFO];
char *info;
char c;
printf("请分别输入 顶点数量、弧的数量、弧是否携带信息(要携带输入1否则输入0)\n");
scanf("%d%d%d",&G.vexnum,&G.arcnum,&infoflag);
printf("依次输入顶点(用-1表示顶点 V1 依此类推)\n");
for(i = 0;i < G.vexnum ; i++)
scanf("%d",&G.vexs[i]);
for(i = 0; i < G.vexnum; i++)
for(j = 0;j < G.vexnum ; j++) {
G.arcs[i][j].adj = INFINITY;
G.arcs[i][j].info = NULL;
}
printf("图中有%d条弧",G.arcnum);
if(G.arcnum>0){
printf("请依次输入这些弧(用两个顶点表示一条弧)及其权值\n\n\n");
}
for(k = 0; k < G.arcnum; k++) {
scanf("%d%d%d",&v1,&v2,&w);
printf("%d条弧输入完成\n\n\n",k+1);
i = LocateVex(G,v1);
j = LocateVex(G,v2);
if(i >= 0 && j >= 0)
G.arcs[i][j].adj = w;
if(infoflag) {
printf("please enter the info:");
while( (c = getchar()) != '#')
str[len++] = c;
info = (char *) malloc(len * sizeof(char));
strcpy(info,str);
G.arcs[i][j].info = info;
}
}
G.kind = DN;
return OK;
}
Status CreateUDN(MGraph &G) {
int i,j,k,len,infoflag,w;
VertexType v1,v2;
char str[MAX_INFO];
char *info;
char c;
printf("请分别输入 顶点数量、边的数量、边是否携带信息(要携带输入1否则输入0)\n");
scanf("%d%d%d",&G.vexnum,&G.arcnum,&infoflag);
printf("依次输入顶点(用-1表示顶点 V1 依此类推)\n");
for(i = 0;i < G.vexnum ; i++)
scanf("%d",&G.vexs[i]);
for(i = 0; i < G.vexnum; i++)
for(j = 0;j < G.vexnum ; j++) {
G.arcs[i][j].adj = INFINITY;
G.arcs[i][j].info = NULL;
}
printf("图中有%d条边\n",G.arcnum);
if(G.arcnum>0){
printf("请依次输入这些边(用两个顶点表示一条边)及其权值\n\n\n");
}
for(k = 0; k < G.arcnum; k++) {
scanf("%d%d%d",&v1,&v2,&w);
printf("%d条边输入完成\n\n\n",k+1);
i = LocateVex(G,v1);
j = LocateVex(G,v2);
if(i >= 0 && j >= 0)
G.arcs[i][j].adj = G.arcs[j][i].adj = w;
if(infoflag) {
printf("please enter the info:");
while( (c = getchar()) != '#')
str[len++] = c;
info = (char *) malloc(len * sizeof(char));
strcpy(info,str);
G.arcs[i][j].info = info;
}
}
G.kind = UDN;
return OK;
}
Status CreateGraph(MGraph &G) {
printf("请输入要创建的图的种类 (有向图:0,有向网:1,无向图:2,无向网:3):\n");
scanf("%d",&G.kind);
switch(G.kind) {
case UDG:
return CreateUDG(G);
break;
case DG:
return CreateDG(G);
case UDN:
return CreateUDN(G);
break;
case DN:
return CreateDN(G);
break;
default:
return ERROR;
}
}
void MiniSpanTree_PRIM(MGraph G,VertexType u){
if(G.kind==DG||G.kind==UDG){
printf("\n此图中不存在权值无法构造最小生成树!\n");
return;
}
else{
printf("从顶点%d出发构造网的最小生成树为\n",u);
if(G.arcnum==0){
printf("\n空树\n");
}
}
struct {
VertexType adjvex;
VRType lowcost;
}closedge[MAX_VERTEX_NUM];
int k=LocateVex(G,u);
for(int j=0;j<G.vexnum;j++){
if(j!=k){
closedge[j]={u,G.arcs[k][j].adj};
}
}
closedge[k].lowcost=0;
for(int i=1;i<G.vexnum;i++){
for(k=0;!closedge[k].lowcost;k++){
}
int min=INFINITY;
for(int s=0;s<G.vexnum;s++){
if(closedge[s].lowcost<min&&closedge[s].lowcost!=0){
k=s;
min=closedge[s].lowcost;
}
}
printf("%d_____(%d)_____%d\n",closedge[k].adjvex,closedge[k].lowcost,G.vexs[k]);
closedge[k].lowcost=0;
for(int j=0;j<G.vexnum;j++){
if(G.arcs[k][j].adj<closedge[j].lowcost){
closedge[j]={G.vexs[k],G.arcs[k][j].adj};
}
}
}
printf("\n\n\n");
}
Status visited[MAX_VERTEX_NUM];
void(*VisitFunc)(VertexType v);
int FirstAdjVex(MGraph G,VertexType v){
int i, j = 0, k;
k = LocateVex(G, v);
if (k < 0)
return ERROR;
if(G.kind%2==1){
j=INFINITY;
}
for (i = 0; i < G.vexnum; i++)
if (G.arcs[k][i].adj != j)
return i;
return -1;
}
int NextAdjVex(MGraph G,VertexType v,VertexType w){
int i, j = 0, k1, k2;
k1 = LocateVex(G, v);
k2 = LocateVex(G, w);
if(G.kind%2==1){
j=INFINITY;
}
for (i = k2+1; i < G.vexnum; i++)
if (G.arcs[k1][i].adj != j)
return i;
return -1;
}
void visit(VertexType i){
printf("%d ",i);
}
typedef VRType QElemType;
typedef struct QNode{
QElemType data;
struct QNode *next;
}*QueuePtr;
typedef struct LinkQueue{
QueuePtr front, rear;
}LinkQueue;
void InitQueue(LinkQueue &Q)
{
Q.front = (QueuePtr)malloc(sizeof(QNode));
if (!Q.front) exit(OVERFLOW);
Q.front->next = NULL;
Q.rear = Q.front;
}
void EnQueue(LinkQueue &Q, QElemType e)
{
QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
if (!p) exit(OVERFLOW);
p->next = NULL;
memcpy(&(p->data), &e, sizeof(QElemType));
Q.rear->next = p;
Q.rear = p;
}
Status QueueEmpty(LinkQueue Q)
{
if (Q.front == Q.rear)
return TRUE;
else
return FALSE;
}
Status DeQueue(LinkQueue &Q, QElemType &e)
{
QueuePtr p = Q.front, q;
if (Q.front == Q.rear)
return FALSE;
q = p->next;
memcpy(&e, &(q->data), sizeof(QElemType));
p->next = q->next;
if (Q.rear == q)
Q.rear = Q.front;
free(q);
return OK;
}
void DFS(MGraph G,int v){
int w;
visited[v] = TRUE;
VisitFunc(G.vexs[v]);
for(w = FirstAdjVex(G,G.vexs[v]); w >= 0; w = NextAdjVex(G,G.vexs[v],G.vexs[w]))
if(!visited[w])
DFS(G,w);
}
void DFSTraverse(MGraph G,void(*Visit)(VertexType v)){
printf("\n深度优先遍历\n");
int v;
VisitFunc=Visit;
for(v=0;v<G.vexnum;v++)
visited[v]=FALSE;
for(v=0;v<G.vexnum;v++)
if(!visited[v])
DFS(G,v);
printf("\n");
}
void BFSTraverse(MGraph G,void(*Visit)(VertexType)){
int v,u,w;
LinkQueue Q;
printf("\n广度优先遍历\n");
for(v=0;v<G.vexnum;v++)
visited[v]=FALSE;
InitQueue(Q);
for(v=0;v<G.vexnum;v++){
if(!visited[v]){
visited[v]=TRUE;
Visit(G.vexs[v]);
EnQueue(Q,v);
while(!QueueEmpty(Q)){
DeQueue(Q,u);
for(w = FirstAdjVex(G,G.vexs[u]); w >= 0; w=NextAdjVex(G,G.vexs[u],G.vexs[w])){
if(!visited[w]){
visited[w]=TRUE;
Visit(G.vexs[w]);
EnQueue(Q,w);
}
}
}
}
}
printf("\n");
}
int main(){
MGraph G;
CreateGraph(G);
MiniSpanTree_PRIM(G,-1);
DFSTraverse(G,visit);
BFSTraverse(G,visit);
return 0;
}