图的基础操作及应用 完整源码
#include <iostream>
#include <windows.h>
#include <iomanip>
using namespace std;
#define MAXINT 65535
#define MAX_VERTEX_NUM 100
#define STACK_INIT_SIZE 100
#define STACK_ADD 10
typedef char InfoType;
typedef int VRType;
typedef char VertexType;
typedef int QElemType;
typedef enum{
DG,
DN,
UDG,
UDN
}GraphKind;
typedef struct arccell{
VRType adj;
InfoType *info;
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct mgraph{
VertexType vexs[MAX_VERTEX_NUM];
AdjMatrix arcs;
int vexnum;
int arcnum;
GraphKind kind;
}MGraph;
typedef struct arcnode {
int adjvex;
struct arcnode *nextarc;
} ArcNode;
typedef struct vnode {
VertexType data;
ArcNode *firstarc;
}VNode, AdjList[MAX_VERTEX_NUM];
typedef struct {
AdjList vertices;
int vexnum;
int arcnum;
int kind;
}ALGraph;
typedef struct qnode{
QElemType data;
struct qnode *prior;
struct qnode *next;
}QNode,*Queue;
typedef struct linkqueue{
Queue front;
Queue rear;
}LinkQueue;
typedef struct sqstack{
int *base;
int *top;
int stacksize;
}SqStack;
typedef struct closedge{
VertexType adjvex;
VRType lowcost;
}ClosEdge[MAX_VERTEX_NUM];
bool visited[100];
bool (* VisitFunc)(int v,ALGraph G);
bool create_graph(ALGraph &g);
bool create_graph(MGraph &g);
bool create_UDN(MGraph &g);
bool create_UDG(ALGraph &g);
int locate_vertex(ALGraph g,VertexType v);
int locate_vertex(MGraph h,VertexType v);
void output(ALGraph g);
void output(MGraph g);
int first_adjvex(ALGraph g,int v);
int next_adjvex(ALGraph g,int v,int w);
void DFS(ALGraph g,int v);
void DFSTraverse(ALGraph g,bool(*Visit)(int v,ALGraph G));
void BFSTraverse(ALGraph g, bool(*Visit)(int v,ALGraph G));
void DFSSearch(ALGraph g,int v, int s, char *PATH);
bool TopologicalSort(ALGraph g);
void MiniSpanTree_P(MGraph G, VertexType u);
int LocateVex(MGraph G,char v);
int LocateVex(ALGraph G,char v);
void FindInDegree(ALGraph G,int indegree[]);
void init_queue(LinkQueue &q);
void en_queue(LinkQueue &q,QElemType e);
void de_queue(LinkQueue &q,QElemType &e);
bool empty_queue(LinkQueue q);
void print_queue(LinkQueue q);
bool init_stack(SqStack &s);
bool push(SqStack &s,int d);
bool pop(SqStack &s,int &d);
bool judge_empty(SqStack s);
bool get_top(SqStack s,int &d);
bool print_stack(SqStack s);
void show();
void switch_channel(int channel);
bool visit(int v,ALGraph G);
ALGraph ga1,ga2;
MGraph gm1,gm2;
char *path = new char[100];
bool found = false;
int w=0,k=0,j=0;
int main()
{
int channel;
do{
show();
cout<<"请输入操作:";
cin>>channel;
switch_channel(channel);
cout<<endl;
}while(1);
return 0;
}
void show()
{
cout<<"图的存储结构的建立\n";
cout<<"1--有向图的邻接表"<<endl;
cout<<"2--有向图的邻接矩阵"<<endl;
cout<<"3--无向图的邻接表"<<endl;
cout<<"4--无向图的邻接矩阵"<<endl;
cout<<"5--深度优先遍历、广度优先遍历"<<endl;
cout<<"6--无向图简单路径"<<endl;
cout<<"7--无向图最小生成树"<<endl;
cout<<"8--有向图拓扑排序"<<endl;
}
void switch_channel(int channel)
{
switch(channel)
{
case 1: create_graph(ga1);output(ga1);break;
case 2: create_graph(gm1);output(gm1);break;
case 3: create_UDG(ga2);output(ga2);break;
case 4: create_UDN(gm2);output(gm2);break;
case 5:{
cout<<"有向图:";
cout<<"深度优先遍历:";
DFSTraverse(ga1,visit);
cout<<"广度优先遍历";
BFSTraverse(ga1,visit);
cout<<endl;
cout<<"无向图:";
cout<<"深度优先遍历:";
DFSTraverse(ga2,visit);
cout<<"广度优先遍历";
BFSTraverse(ga2,visit);
cout<<endl;
}break;
case 6: {
int v,m;
cout<<"请输入要查询的路径起始端点编号:";
cin>>v;
cout<<"请输入要查询的路径尾端点编号:";
cin>>m;
DFSSearch(ga2,1,3,path);
cout<<endl;
}break;
case 7: output(gm2);MiniSpanTree_P(gm2,gm2.vexs[0]);cout<<endl;break;
case 8: output(ga1); TopologicalSort(ga1); cout<<endl;break;
default:exit(1);break;
}
}
bool create_graph(ALGraph &g)
{
char ch;
char v1,v2;
ArcNode *p;
int i,j,k;
cout<<"请输入有向图的顶点个数:";
cin>>g.vexnum;
cout<<"请输入有向图的弧个数:";
cin>>g.arcnum;
cout<<"请输入图中的顶点"<<endl;
for(i =0 ;i < g.vexnum; i++)
{
cin>>ch;
g.vertices[i].data = ch;
g.vertices[i].firstarc = NULL;
}
for(k = 0;k < g.arcnum; k++)
{
cout<<"请输入图中第"<<k+1<<"条弧的起点和终点"<<endl;
cin>>v1>>v2;
i = locate_vertex(g,v1);
j = locate_vertex(g,v2);
p = new ArcNode;
if(!p)
return false;
p->adjvex = j;
p->nextarc = g.vertices[i].firstarc;
g.vertices[i].firstarc = p;
}
return true;
}
bool create_graph(MGraph &g)
{
int i,j,k,w;
char v1,v2;
cout<<"请输入有向图的顶点个数:";
cin>>g.vexnum;
cout<<"请输入有向图的弧个数:";
cin>>g.arcnum;
cout<<"请输入顶点:";
for(i = 0;i < g.vexnum; i++)
cin>>g.vexs[i];
for(i = 0;i < g.vexnum; i++)
for(j = 0;j < g.vexnum; j++)
g.arcs[i][j].adj = MAXINT;
for(k = 0;k < g.arcnum; k++)
{
cout<<"输入一条边依附的顶点及权值: ";
cin>>v1>>v2>>w;
i = locate_vertex(g,v1);
j = locate_vertex(g,v2);
g.arcs[i][j].adj = w;
}
return true;
}
bool create_UDN(MGraph &g)
{
int i,j,k,w;
char v1,v2;
cout<<"请输入无向图的顶点个数:";
cin>>g.vexnum;
cout<<"请输入无向图的弧个数:";
cin>>g.arcnum;
cout<<"请输入顶点:";
for(i = 0;i < g.vexnum; i++)
cin>>g.vexs[i];
for(i = 0;i < g.vexnum; i++)
for(j = 0;j < g.vexnum; j++)
g.arcs[i][j].adj = MAXINT;
for(k = 0;k < g.arcnum; k++)
{
cout<<"输入一条边依附的顶点及权值: ";
cin>>v1>>v2>>w;
i = locate_vertex(g,v1);
j = locate_vertex(g,v2);
g.arcs[i][j].adj = w;
g.arcs[j][i].adj = w;
}
return true;
}
bool create_UDG(ALGraph &g)
{
int i,j,k,w;
char v1,v2;
ArcNode *p;
ArcNode *p2;
cout<<"请输入无向图的顶点个数:";
cin>>g.vexnum;
cout<<"请输入无向图的弧个数:";
cin>>g.arcnum;
cout<<"输入各个顶点:\n";
for(i = 0;i < g.vexnum; i++)
{
cin>>g.vertices[i].data;
g.vertices[i].firstarc = NULL;
}
cout<<"输入边上的两个顶点:\n";
for(k = 0;k < g.arcnum; k++)
{
cin>>v1>>v2;
i = locate_vertex(g,v1);
j = locate_vertex(g,v2);
p = new ArcNode;
if(!p)
return false;
p->adjvex = j;
p->nextarc = g.vertices[i].firstarc;
g.vertices[i].firstarc = p;
p2 = new ArcNode;
if(!p2)
return false;
p2->adjvex = i;
p2->nextarc = g.vertices[j].firstarc;
g.vertices[j].firstarc = p2;
}
return true;
}
int locate_vertex(ALGraph g,VertexType v)
{
int i;
for(i = 0;i < g.vexnum; i++)
if(g.vertices[i].data == v)
return i;
return -1;
}
int locate_vertex(MGraph g,VertexType v)
{
int i;
for(i = 0;i < g.vexnum; i++)
if(g.vexs[i] == v)
return i;
return -1;
}
void output(ALGraph g)
{
ArcNode *p;
int i;
cout<<"当前图结构:\n";
for(i = 0;i < g.vexnum; i++)
{
cout<<g.vertices[i].data;
p = g.vertices[i].firstarc;
while(p)
{
cout<<"-->"<<g.vertices[p->adjvex].data;
p = p->nextarc;
}
cout<<endl;
}
}
void output(MGraph g)
{
int i,j;
for(i=0;i<g.vexnum;i++)
{
for(j=0;j<g.vexnum;j++)
{
if(g.arcs[i][j].adj == MAXINT)
cout<<setw(7)<<"NULL"<<" ";
else
cout<<setw(7)<<g.arcs[i][j].adj<<" ";
}
cout<<endl;
}
}
int first_adjvex(ALGraph g,int v)
{
if(!g.vertices[v].firstarc)
return -1;
return g.vertices[v].firstarc->adjvex;
}
int next_adjvex(ALGraph g,int v,int w)
{
ArcNode *p;
int flag=0;
p = g.vertices[v].firstarc;
while(p)
{
if(p->adjvex == w)
{
flag = 1;
break;
}
p = p->nextarc;
}
if(flag)
{
if(p->nextarc)
return p->nextarc->adjvex;
}
return -1;
}
void DFS(ALGraph g,int v)
{
visited[v] = TRUE;
VisitFunc(v,g);
int w;
for(w=first_adjvex(g,v);w>=0;w=next_adjvex(g,v,w))
if (!visited[w])
DFS(g, w);
}
void DFSTraverse(ALGraph g,bool(*Visit)(int v,ALGraph G))
{
VisitFunc = Visit;
int v;
for (v=0; v<g.vexnum; ++v)
visited[v] = FALSE;
for (v=0; v<g.vexnum; ++v)
if (!visited[v])
DFS(g, v);
}
void BFSTraverse(ALGraph g, bool(*Visit)(int v,ALGraph G))
{
LinkQueue Q;
int v,u,w;
VertexType e;
for (v=0; v<g.vexnum; ++v)
visited[v] = FALSE;
init_queue(Q);
for ( v=0; v<g.vexnum; ++v )
if ( !visited[v])
{
visited[v] = true;
Visit(v,g);
en_queue(Q, v);
while (!empty_queue(Q))
{
de_queue(Q, u);
for(w=first_adjvex(g, u); w>=0; w=next_adjvex(g,u,w))
if ( ! visited[w])
{
visited[w]=TRUE;
Visit(w,g);
en_queue(Q, w);
}
}
}
}
void DFSSearch(ALGraph g, int v, int s, char *PATH)
{
visited[v] = true;
PATH[j]=g.vertices[v].data;j++;
for (w=first_adjvex(g,v);w>=0&&!found; w=next_adjvex(g,v,w))
if (w==s)
{
found = true;
PATH[j]=g.vertices[w].data;
cout<<"简单路径为:";
for (k=0;k<=j;k++)
cout<<PATH[k]<<" ";
}
else if (!visited[w])
DFSSearch(g,w,s,PATH);
if(!found) j--;
}
void init_queue(LinkQueue& Q)
{
Q.front=Q.rear=(Queue)malloc(sizeof(QNode));
Q.front->next = Q.rear->prior = NULL;
}
void en_queue( LinkQueue& Q, QElemType e )
{
Queue p;
p = (Queue) malloc (sizeof(QNode));
p->data = e; p->next = NULL;
p->prior = Q.front;
Q.rear->next = p; Q.rear = p;
}
void de_queue( LinkQueue& Q, QElemType& e )
{
Q.front = Q.front->next; e = Q.front->data;
}
bool empty_queue(LinkQueue q)
{
if(q.front == q.rear)
return true;
return false;
}
void print_queue(LinkQueue Q)
{
Queue q;
q = Q.front;
while(q!=Q.rear)
{
cout<<q->data<<" ";
q = q->next;
}
}
bool init_stack(SqStack &s)
{
s.base = new int[STACK_INIT_SIZE];
if(!s.base)
return false;
s.top = s.base;
s.stacksize = STACK_INIT_SIZE;
return true;
}
bool push(SqStack &s,int d)
{
if(s.top - s.base >= s.stacksize)
{
s.base = (int *)realloc(s.base,(s.stacksize + STACK_ADD)*sizeof(int));
if(!s.base)
return false;
s.top = s.base + s.stacksize;
s.stacksize += STACK_ADD;
}
*s.top++ = d;
return true;
}
bool pop(SqStack &s,int &d)
{
if(judge_empty(s))
return false;
d = *(--s.top);
return true;
}
bool judge_empty(SqStack s)
{
if(s.top == s.base)
return true;
return false;
}
bool get_top(SqStack s,int &d)
{
if(judge_empty(s))
return false;
d = *(s.top - 1);
return true;
}
bool print_stack(SqStack s)
{
int *t;
t = s.base;
while(t != s.top)
{
cout<<*t<<" ";
t++;
}
cout<<endl;
return true;
}
bool TopologicalSort(ALGraph g)
{
SqStack s;
int i,count,k;
int indegree[MAX_VERTEX_NUM];
ArcNode *p;
init_stack(s);
for(i=0;i<g.vexnum;i++)
indegree[i] = 0;
FindInDegree(g,indegree);
for(i=0;i<g.vexnum;i++)
{
if(!indegree[i])
push(s,i);
}
count = 0;
while(!judge_empty(s))
{
pop(s,i);
cout<<setw(5)<<g.vertices[i].data;
count++;
for(p=g.vertices[i].firstarc;p;p=p->nextarc)
{
k=p->adjvex;
if(!(--indegree[k]))
push(s,k);
}
}
cout<<endl;
if (count<g.vexnum)
{
cout<<"有回路"<<endl;
return true;
}
cout<<"无回路,拓扑序列如上"<<endl;
return false;
}
void MiniSpanTree_P(MGraph g, VertexType u)
{
ClosEdge closedge;
int i,j,k,t,min;
i=j=k=t=min=0;
k = LocateVex(g,u);
for(j=0;j<g.vexnum;j++)
if(j != k)
{
closedge[j].adjvex = u;
closedge[j].lowcost = g.arcs[k][j].adj;
}
closedge[k].lowcost = 0;
cout<<"最小生成树上的边有:"<<endl;
for(i=1;i<g.vexnum;i++)
{
for(j=0;j<g.vexnum;j++)
if(closedge[j].lowcost != 0)
{
min=closedge[j].lowcost;
k=j;
break;
}
for(t=0;t<g.vexnum;t++)
if(closedge[t].lowcost != 0 && closedge[t].lowcost<min)
{
k=t;
min=closedge[t].lowcost;
}
cout<<closedge[k].adjvex<<"-->"<<g.vexs[k]<<endl;
closedge[k].lowcost = 0;
for(j=0;j<g.vexnum;j++)
if(g.arcs[k][j].adj < closedge[j].lowcost)
{
closedge[j].adjvex = g.vexs[k];
closedge[j].lowcost = g.arcs[k][j].adj;
}
}
}
int LocateVex(MGraph g,char v)
{
int i;
for(i=0;i<g.vexnum;i++)
if(g.vexs[i]==v)
return i;
return -1;
}
int LocateVex(ALGraph g,char v)
{
int i;
for(i=0;i<g.vexnum;i++)
if(g.vertices[i].data==v)
return i;
return -1;
}
void FindInDegree(ALGraph G,int indegree[])
{
int i;ArcNode *p;
for (i=0;i<G.vexnum;i++)
{
p=G.vertices[i].firstarc;
while (p)
{
indegree[p->adjvex]++;
p=p->nextarc;
}
}
}
bool visit(int e,ALGraph G)
{
cout<<G.vertices[e].data<<" ";
return true;
}