急!!!!!数据结构课程设计

对任意给定的图(顶点数不小于20,边数不少于30,图的类型可以是有向图、无向图、有向网、无向网),能够输入图的顶点和边(或弧)的信息,并存储到相应存储结构(邻接矩阵、邻接表、十字链表、邻接多重表,任选其中两种类型),对自己所创建的图完成以下操作:
1、 对无向图求每个顶点的度,或对有向图求每个顶点的入度和出度(5分)
2、 完成插入顶点和边(或弧)的功能(5分)
3、 完成删除顶点和边(或弧)的功能(5分)
4、 两种存储结构的转换(5分),如果其中一种存储结构为十字链表或邻接多重表则增加5分。
5、 输出图的深度优先遍历序列或广度优先遍历序列(5分)
6、 求图的深度优先或广度优先的生成树(或生成森林)(存储结构为孩子-兄弟链表),并对生成树进行遍历(15分)
7、 判断图的连通性,输出连通分量的个数(5分)
8、 判断图中是否存在环,无向图(5分),有向图(10分)
9、 给出顶点u和v,判断u到v是否存在路径(5分)
10、求顶点u到v的一条简单路径(10分)
11、求顶点u到v的所有简单路径(15分)
12、求顶点u到v的最短路径(10分)
13、求顶点u到其余各顶点的最短路径(15分)
14、求任两个顶点之间的最短路径(15分)
15、求最小生成树(15分)
16、对于有一个源点和一个汇点的有向网,求关键路径(20分)

编程环境可以是C、VC++、JAVA,每位同学从上述题目中选择100分的题目,注意,必须选择第1-6题。

八九十分够了 谢谢

第1个回答  2010-07-11
#include <iostream.h>
#include <malloc.h>
#include <stdlib.h>
#define MAX_VERTEX_NUM 30 //最大顶点数
#define INFINITY 10000000 //无穷大

typedef struct ArcCell{
int adj;
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

typedef struct{
char vexs[MAX_VERTEX_NUM];
AdjMatrix arcs;
int vexnum,arcnum;
}MGraph;

//查询顶点位置

int LocateVex(MGraph G,char v){
int i=0;
while(G.vexs[i]!=v&&i<G.vexnum)
i++;
return i;
}

//创建图的邻接矩阵

MGraph CreateMGraph(){
MGraph G;
int i,j,k;
int w;
char v1,v2;
cout<<"请输入图的顶点数:";
cin>>G.vexnum;
cout<<"请输入图的弧数:";
cin>>G.arcnum;
for(i=0;i<G.vexnum;i++){
cout<<"请输入第"<<i+1<<"个顶点:";
cin>>G.vexs[i];
}
for(i=0;i<G.vexnum;i++)
for(j=0;j<G.vexnum;j++)
G.arcs[i][j].adj=INFINITY;
for(k=0;k<G.arcnum;k++){
cout<<"请输入弧"<<k+1<<"所关联的顶点和权值:";
cin>>v1>>v2>>w;
if(LocateVex(G,v1)<G.vexnum)
i=LocateVex(G,v1);
else{
cout<<"没有找到此顶点!"<<endl;
k--;
continue;
}
if(LocateVex(G,v2)<G.vexnum)
j=LocateVex(G,v2);
else{
cout<<"没有找到此顶点!"<<endl;
k--;
continue;
}
G.arcs[i][j].adj=w;
G.arcs[j][i]=G.arcs[i][j];
}
cout<<"MGraph创建成功!"<<endl;
return G;
}

//……………………输出MGraph…………………

void PrintMGraph(MGraph G){
cout<<"图的邻接矩阵"<<endl;
int i,j;
for(i=0;i<G.vexnum;i++)
cout<<" "<<G.vexs[i];
cout<<endl;
for( i=0;i<G.vexnum;i++){
cout<<G.vexs[i]<<" ";
for( j=0;j<G.vexnum;j++){
if(G.arcs[i][j].adj!=INFINITY)
cout<<G.arcs[i][j].adj<<" ";
else
cout<<"∞"<<" ";
}
cout<<endl;
}
cout<<"--------------------------------------------"<<endl;
}

//……………………求各个顶点的度…………………

void Vdu(MGraph G){ //求各个顶点的度
int i,j;
int V[20];
for(i=0;i<G.vexnum;i++){
int count=0;
for(j=0;j<G.vexnum;j++)
if(G.arcs[i][j].adj!=INFINITY)
count++;
V[i]=count;
}
for(i=0;i<G.vexnum;i++)
cout<<endl<<"第"<<i+1<<"个顶点"<<G.vexs[i]<<"的度为:"<<V[i]<<endl;
}

//……………………插入顶点…………………

void InsertVex(MGraph &G){
char v;
int i,j;
cout<<"请输入你想插入的顶点:";
cin>>v;
i=G.vexnum++;
G.vexs[i]=v;
for(j=0;j<G.vexnum;j++)
G.arcs[i][j].adj=INFINITY;
j=G.vexnum-1;
for(i=0;i<G.vexnum;i++)
G.arcs[i][j].adj=INFINITY;
cout<<endl<<"插入成功!"<<endl;
}

//……………………插入弧…………………

void InsertArc(MGraph &G){
char v1,v2;
int i,j,w;
cout<<"请输入你要插入的弧所关联的顶点和权值:";
cin>>v1>>v2>>w;
if(LocateVex(G,v1)<G.vexnum&&LocateVex(G,v2)<G.vexnum){
i=LocateVex(G,v1);
j=LocateVex(G,v2);
G.arcs[i][j].adj=w;
G.arcs[j][i]=G.arcs[i][j];
cout<<endl<<"插入成功!"<<endl;
}else{
cout<<"没有找到关联的顶点!"<<endl;
}
}

//……………………删除顶点…………………

void DeleteVex(MGraph &G){
int i,j;
char v;
cout<<"请输入你所要删除的顶点:";
cin>>v;
if(LocateVex(G,v)<G.vexnum){
int l=LocateVex(G,v);
for(i=l;i<G.vexnum-1;i++)
G.vexs[i]=G.vexs[i+1];
for(i=l;i<G.vexnum-1;i++)
for(j=0;j<G.vexnum;j++)
G.arcs[i][j]=G.arcs[i+1][j];
for(i=0;i<G.vexnum;i++)
for(j=l;j<G.vexnum-1;j++)
G.arcs[i][j]=G.arcs[i][j+1];
G.vexnum--;
cout<<"已成功删除此顶点!"<<endl;
}else
cout<<"没有此顶点!"<<endl;
}

//……………………删除弧…………………

void DeleteArc(MGraph &G){
int i,j;
char v1,v2;
cout<<"请输入你要删除的弧所关联的顶点";
cin>>v1>>v2;
if(LocateVex(G,v1)<G.vexnum&&LocateVex(G,v2)<G.vexnum){
i=LocateVex(G,v1);
j=LocateVex(G,v2);
G.arcs[i][j].adj=INFINITY;
G.arcs[j][i]=G.arcs[i][j];
cout<<"已成功删除此弧!"<<endl;
}else
cout<<"没有找到此弧所关联的顶点!"<<endl;

}

typedef struct ArcNode{
int adjvex;
struct ArcNode *nextarc;
}ArcNode;

typedef struct vnode{
char data;
ArcNode *firstarc;
}vnode,adjlist;

typedef struct {
adjlist vertices[MAX_VERTEX_NUM];
int vexnum,arcnum;
}ALGraph;

//……………………创建图的邻接表…………………

ALGraph CreateUDG(MGraph G){
ALGraph gra;
int i,j;
ArcNode *arc,*tem,*p;
for(i=0;i<G.vexnum;i++){
gra.vertices[i].data=G.vexs[i];
gra.vertices[i].firstarc=NULL;
}
for(i=0;i<G.vexnum;i++){
for(j=0;j<G.vexnum;j++){
if(gra.vertices[i].firstarc==NULL){
if(G.arcs[i][j].adj!=INFINITY){
arc=(ArcNode*)malloc(sizeof(ArcNode));
arc->adjvex=j;
gra.vertices[i].firstarc=arc;
arc->nextarc=NULL;
p=arc;
j++;
while(G.arcs[i][j].adj!=INFINITY&&j<G.vexnum){
tem=(ArcNode*)malloc(sizeof(ArcNode));
tem->adjvex=j;
gra.vertices[i].firstarc=tem;
tem->nextarc=arc;
arc=tem;
j++;
}

}
}else{
if(G.arcs[i][j].adj!=INFINITY){
arc=(ArcNode*)malloc(sizeof(ArcNode));
arc->adjvex=j;
p->nextarc=arc;
arc->nextarc=NULL;
p=arc;
}
}
}
}

gra.vexnum=G.vexnum;
gra.arcnum=G.arcnum;
cout<<"ALGraph创建成功!"<<endl;
return gra;
}

//……………………输出ALGraph…………………

void PrintUDG(ALGraph gra){
int i;
ArcNode *p;
cout<<"图的各顶点为:"<<endl;
for(i=0;i<gra.vexnum;i++)
cout<<gra.vertices[i].data<<" ";
cout<<endl;
cout<<"图的邻接表为:"<<endl;
for(i=0;i<gra.vexnum;i++){
cout<<i<<" "<<gra.vertices[i].data;
p=gra.vertices[i].firstarc;
while(p){
cout<<"->"<<p->adjvex;
p=p->nextarc;
}
cout<<endl;
}

}

//……定义全局变量……
int visited[MAX_VERTEX_NUM];
int we;

//……求第一个邻接点……
int firstadjvex(ALGraph gra,vnode v){
if(v.firstarc!=NULL)
return v.firstarc->adjvex;
else
return -1;
}

//……求相对于w的下一个邻接点
int nextadjvex(ALGraph gra,vnode v,int w){
ArcNode *p;
p=v.firstarc;
while(p!=NULL&&p->adjvex!=w){
p=p->nextarc;
}
if(p->adjvex==w&&p->nextarc!=NULL){
p=p->nextarc;
return p->adjvex;
}else
return -1;
}

//……………………图的深度优先遍历…………………
void DFS(ALGraph gra,int i){
visited[i]=1;
int we1;
cout<<gra.vertices[i].data<<" ";
for(we=firstadjvex(gra,gra.vertices[i]);we>=0;we=nextadjvex(gra,gra.vertices[i],we)){
we1=we;
if(visited[we]==0)
DFS(gra,we);
we=we1;
}
}

void DFSTravers(ALGraph gra){
int i;
for(i=0;i<gra.vexnum;i++){
visited[i]=0;
}
for(i=0;i<gra.vexnum;i++){
if(visited[i]==0)
DFS(gra,i);
}
cout<<endl;
}
//…………………………………………………………………

//……………………队列定义和基本操作……………………

typedef struct qnode{
int data;
struct qnode *next;
}qnode,*queueptr;

typedef struct{
queueptr front;
queueptr rear;
}linkqueue;
//……初始化队列………

void initqueue(linkqueue &q){
q.rear=(queueptr)malloc(sizeof(qnode));
q.front=q.rear;
q.front->next=NULL;
}
//……入队列………
int enqueue(linkqueue &q,int e){
queueptr p;
p=(queueptr)malloc(sizeof(qnode)); //系统生成qnode节点并赋予p
if(!p)
return 0;
else{
p->data=e;
p->next=NULL;
q.rear->next=p;
q.rear=p;
return 1;
}

}

//……出队列……

int dequeue(linkqueue &q,int &e){
queueptr p;
if(q.front==q.rear)
return 0;
p=q.front->next;
e=p->data;
q.front->next=p->next;
if(q.rear==p)
q.rear=q.front;
free(p);
return 1;
}

//……判断队列是否为空……
int queueempty(linkqueue q){
if(q.front==q.rear)
return 1;
return 0;
}
//………………………………………………………………………

//……………………图的广度优先遍历…………………

void BFSTravers(ALGraph gra){
int i,e;
linkqueue q;
for(i=0;i<gra.vexnum;i++)
visited[i]=0;
initqueue(q); //附设队列存储已经被访问的路径长度为1 2...的顶点

for(i=0;i<gra.vexnum;i++)
if(!visited[i]){
visited[i]=1;
cout<<gra.vertices[i].data<<" ";
enqueue(q,i);
while(!queueempty(q)){
dequeue(q,e);
for(we=firstadjvex(gra,gra.vertices[e]);we>=0;we=nextadjvex(gra,gra.vertices[e],we)){
if(!visited[we]){
visited[we]=1;
cout<<gra.vertices[we].data<<" ";
enqueue(q,we);
}
}
}
}
cout<<endl;
}

//……………………求图的连通分支…………………

void DFSTraversFL(ALGraph gra){
int i,count=1;
for(i=0;i<gra.vexnum;i++){
visited[i]=0;
}
for(i=0;i<gra.vexnum;i++){
if(visited[i]==0){
cout<<"第"<<count<<"个连通分支为:";
DFS(gra,i); //对连通图,只需从一个顶点出发深度优先遍历即可访问所有顶点
cout<<endl;
count++;
}
}
}

//……………………用普里姆算法求最小生成树…………………
void PRIM(ALGraph gra,int g[][MAX_VERTEX_NUM],int n){
int lowcost[MAX_VERTEX_NUM],prevex[MAX_VERTEX_NUM];
int i,j,k,min;
for(i=2;i<=n;i++){
lowcost[i]=g[1][i];
prevex[i]=1;
}
lowcost[1]=0;
for(i=2;i<=n;i++){
min=INFINITY;
k=0;
for(j=2;j<=n;j++)
if(lowcost[j]<min&&lowcost[j]!=0){
min=lowcost[j];
k=j;
}
cout<<gra.vertices[prevex[k]-1].data<<" "<<gra.vertices[k-1].data<<" "<<min;
lowcost[k]=0;
for(j=2;j<=n;j++)
if(g[k][j]<lowcost[j]){
lowcost[j]=g[k][j];
prevex[j]=k;
}
cout<<endl;
}
}

//…………求最短路径…………

void ShortPath(MGraph G,char ch){ //迪杰斯特拉算法实现,某点到其余各点
int i,j,min,k,t,w;
int v=0;
int final[MAX_VERTEX_NUM];
int lowcost[MAX_VERTEX_NUM];
int q[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
k=LocateVex(G,ch);
for(i=0;i<G.vexnum;i++){
final[i]=0;
lowcost[i]=G.arcs[k][i].adj;
for(j=0;j<G.vexnum;j++)
q[i][j]=0;
if(lowcost[i]<INFINITY){
q[i][k]=1;
q[i][i]=1;
}
}
lowcost[k]=0;
final[k]=1;
for(i=0;i<G.vexnum;i++){
min=INFINITY;
for(j=0;j<G.vexnum;j++)
if(!final[j])
if(lowcost[j]<min){
min=lowcost[j];
v=j;
}
final[v]=1;
for(w=0;w<G.vexnum;w++)
if(!final[w]&&(min+G.arcs[v][w].adj<lowcost[w])){
lowcost[w]=min+G.arcs[v][w].adj;
for(t=0;t<G.vexnum;t++)
q[w][t]=q[v][t];
q[w][w]=1;
}

}

for(i=0;i<G.vexnum;i++){
if(i!=k){
cout<<ch<<" to "<<G.vexs[i]<<endl;
cout<<"最短路径:";
if(lowcost[i]<INFINITY){
for(j=0;j<G.vexnum;j++)
if(q[i][j]&&j!=i)
cout<<G.vexs[j]<<" ";
cout<<G.vexs[i];
cout<<"长度:"<<lowcost[i]<<endl;

}else
cout<<"不存在!"<<endl;
}
}

}

typedef struct CSNode{
char data;
struct CSNode *firstchild,*nextsibling;
}CSNode,*CSTree;

//……………………深度优先生成树…………………

void DFSTree(ALGraph gra,int v,CSTree &T){ //深度优先搜索后顺序输出
visited[v]=1;
int w,first=1;
CSTree p,q;
for(w=firstadjvex(gra,gra.vertices[v]);w>=0;w=nextadjvex(gra,gra.vertices[v],w))
if(!visited[w]){
p=(CSTree)malloc(sizeof(CSNode));
p->data=gra.vertices[w].data;
p->firstchild=NULL;
p->nextsibling=NULL;
if(first){
T->firstchild=p;
first=0;
}else
q->nextsibling=p;
q=p;
DFSTree(gra,w,q);
}
}

void DFSForest(ALGraph gra,CSTree &T){
T=NULL;
CSTree p,q;
int v;
for(v=0;v<gra.vexnum;v++)
visited[v]=0;
for(v=0;v<gra.vexnum;v++)
if(!visited[v]){
p=(CSTree)malloc(sizeof(CSNode));
p->data=gra.vertices[v].data;
p->firstchild=NULL;
p->nextsibling=NULL;
if(!T)
T=p;
else
q->nextsibling=p;
q=p;
DFSTree(gra,v,p);
}
}

//……………………先序遍历深度优先生成树…………………

void Preorder(CSTree T){
if(T){
cout<<T->data<<" ";
Preorder(T->firstchild);
Preorder(T->nextsibling);
}
cout<<endl;
}

//……………………求u到v之间的最短路径…………………

void shortestdistance(MGraph G){
int i,u,v,w,S,E;
char start,end;
int Distance[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

cout<<"请输入两个顶点:";
cin>>start>>end;
while(LocateVex(G,start)>=G.vexnum||LocateVex(G,end)>=G.vexnum){
cout<<"没有找到关联的顶点!请重新输入:";
cin>>start>>end;
}
for(i=0;i<G.vexnum;i++)
G.arcs[i][i].adj=0;
for(u=0;u<G.vexnum;u++)
for(v=0;v<G.vexnum;v++)
Distance[u][v]=G.arcs[u][v].adj;
for(u=0;u<G.vexnum;u++)
for(v=0;v<G.vexnum;v++)
for(w=0;w<G.vexnum;w++)
if(Distance[u][w]+Distance[w][v]<Distance[u][v])
Distance[u][v]=Distance[u][w]+Distance[w][v];

S=LocateVex(G,start);
E=LocateVex(G,end);
if(Distance[S][E]==INFINITY)
cout<<start<<"到"<<end<<"的最短路径不存在!"<<endl;
else
cout<<start<<"到"<<end<<"的最短路径为:"<<Distance[S][E]<<endl;
}

//……………………求所有顶点之间的最短路径…………………

void shortdistance(MGraph G){ //弗洛依德算法实现,任意两顶点
int i,j,u,v,w;
int D[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
for(i=0;i<G.vexnum;i++)
G.arcs[i][i].adj=0;
for(u=0;u<G.vexnum;u++)
for(v=0;v<G.vexnum;v++)
D[u][v]=G.arcs[u][v].adj;
for(u=0;u<G.vexnum;u++)
for(v=0;v<G.vexnum;v++)
for(w=0;w<G.vexnum;w++)
if(D[u][w]+D[w][v]<D[u][v])
D[u][v]=D[u][w]+D[w][v];

for(i=0;i<G.vexnum;i++)
for(j=0;j<G.vexnum;j++)
if(D[i][j]==INFINITY)
cout<<G.vexs[i]<<"到"<<G.vexs[j]<<"的最短路径不存在!"<<endl;
else
cout<<G.vexs[i]<<"到"<<G.vexs[j]<<"的最短路径为:"<<D[i][j]<<endl;
}

void main(){
int i,j;
char ch='y';
MGraph G;
G.vexnum=0;
ALGraph gra;
gra.vexnum=0;
int t[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
CSTree T=NULL;
while(ch=='y'){

cout<<"************************************************************"<<endl;
cout<<" MENU"<<endl;
cout<<"************************************************************"<<endl;
cout<<" "<<"1 |利用邻接矩阵创建图"<<endl;
cout<<" "<<"2 |显示图的邻接矩阵"<<endl;
cout<<" "<<"3 |求各顶点的度"<<endl;
cout<<" "<<"4 |插入顶点"<<endl;
cout<<" "<<"5 |插入弧"<<endl;
cout<<" "<<"6 |删除顶点"<<endl;
cout<<" "<<"7 |删除弧"<<endl;
cout<<" "<<"8 |用邻接矩阵创建邻接表UDG"<<endl;
cout<<" "<<"9 |显示图的邻接表"<<endl;
cout<<" "<<"10 |深度优先便利序列"<<endl;
cout<<" "<<"11 |广度优先便利序列"<<endl;
cout<<" "<<"12 |图的连通分支"<<endl;
cout<<" "<<"13 |求连通图最小生成树"<<endl;
cout<<" "<<"14 |求任意顶点到其它顶点的最短路径"<<endl;
cout<<" "<<"15 |求图的深度优先生成树"<<endl;
cout<<" "<<"16 |对生成树进行先序遍历"<<endl;
cout<<" "<<"17 |求两点间的最短路径"<<endl;
cout<<" "<<"18 |求所有点之间的最短路径"<<endl;
cout<<" "<<"0 |退出!"<<endl;
cout<<"***********************************************************"<<endl;
cout<<endl<<"请选择你要进行的操作:";
cin>>i;
switch(i){
case 1:
if(G.vexnum==0)
G=CreateMGraph();
else
cout<<"MGraph已经创建!"<<endl;
break;
case 2:
if(G.vexnum!=0)
PrintMGraph(G);
else
cout<<"MGraph为空!"<<endl;
break;
case 3:
if(G.vexnum==0)
cout<<"请先创建MGraph!"<<endl;
else
Vdu(G);
break;
case 4:
if(G.vexnum==0)
cout<<"请先创建MGraph!"<<endl;
else
InsertVex(G);
break;
case 5:
if(G.vexnum==0)
cout<<"请先创建MGraph!"<<endl;
else
InsertArc(G);
break;
case 6:
if(G.vexnum==0)
cout<<"请先创建MGraph!"<<endl;
else
DeleteVex(G);
break;
case 7:
if(G.vexnum==0)
cout<<"请先创建MGraph!"<<endl;
else
DeleteArc(G);
break;
case 8:
if(G.vexnum==0)
cout<<"请先创建MGraph!"<<endl;
else{
gra=CreateUDG(G);
}
break;
case 9:
if(gra.vexnum!=0)
PrintUDG(gra);
else
cout<<"UDG为空!"<<endl;
break;
case 10:
if(gra.vexnum!=0){
cout<<"图的深度优先遍历序列为:";
DFSTravers(gra);
}
else
cout<<"请先创建ALGraph!"<<endl;
break;
case 11:
if(gra.vexnum!=0){
cout<<"图的广度优先遍历序列为:";
BFSTravers(gra);
}
else
cout<<"请先创建ALGraph!"<<endl;
break;
case 12:
if(gra.vexnum!=0){
cout<<"图的连通分支如下:"<<endl;
DFSTraversFL(gra);
}
else
cout<<"请先创建ALGraph!"<<endl;
break;
case 13:
if(gra.vexnum!=0){
for(i=0;i<G.vexnum;i++)
for(j=0;j<G.vexnum;j++)
t[i+1][j+1]=G.arcs[i][j].adj;
cout<<"图的最小生成树为:"<<endl;
PRIM(gra,t,G.vexnum);
}
else
cout<<"请先创建ALGraph!"<<endl;
break;
case 14:
if(G.vexnum==0)
cout<<"请先创建MGraph!"<<endl;
else{
char ch;
cout<<"请选择一个顶点:";
cin>>ch;
while(LocateVex(G,ch)>=G.vexnum){
cout<<"没有找到此顶点!请重新选择一个顶点:";
cin>>ch;
}
ShortPath(G,ch);
}
break;
case 15:
if(gra.vexnum==0)
cout<<"请先创建ALGraph!"<<endl;
else
DFSForest(gra,T);
break;
case 16:
if(!T)
cout<<"请先求深度优先生成树!"<<endl;
else{
Preorder(T);
cout<<"深度优先生成树已成功创建!"<<endl;
}
break;
case 17:
if(G.vexnum==0)
cout<<"请先创建MGraph!"<<endl;
else
shortestdistance(G);
break;
case 18:
if(G.vexnum==0)
cout<<"请先创建MGraph!"<<endl;
else
shortdistance(G);
break;
case 0:
exit(1);
default:
cout<<"请在0~18之间进行选择!"<<endl;
}
cout<<"是否继续y/n:";
cin>>ch;
system("cls");

}

}本回答被提问者采纳
相似回答