数据结构图的基本操作.docx
《数据结构图的基本操作.docx》由会员分享,可在线阅读,更多相关《数据结构图的基本操作.docx(24页珍藏版)》请在冰豆网上搜索。
数据结构图的基本操作
数据结构---图的基本操作
#include"stdio.h"
#include"malloc.h"
#defineMAX_VERTEX_NUM20
#defineOK1
#defineerror-1
#defineERROR0
#defineErrorInput-2
typedefintVertexType;
typedefintStatus;
intCHIOCE;//用来接收用户的选择
intVEXNUM,ARCNUM;//用来接收用户输入的顶点和弧数目
inti;
typedefstructArcNode
{
intadjvex;//该弧所指向的顶点的位置
structArcNode*nextarc;//指向下一条弧的指针
//InfoType*info;//相关信息
}ArcNode;
typedefstructVNode
{
VertexTypedata;//顶点信息(可放权值)
ArcNode*firstarc;//指向第一条依附该顶点的弧的指针
}VNode,AdjList[MAX_VERTEX_NUM];
typedefstruct
{
AdjListvertices;
intvexnum,arcnum;//vexcount;//图的当前顶点和弧数和顶点计数,count记录真实结点个数
intkind;//图的种类
}ALGraph;
typedefintElemType;
#defineNULL0
typedefintElemType;
typedefstructQNode
{
ElemTypedata;
structQNode*next;
}QNode,*QueuePtr;
typedefstruct
{
QueuePtrfront;
QueuePtrrear;
}LinkQueue;
boolInitQueue(LinkQueue&Q)
{
Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
if(!
Q.front)returnfalse;
Q.front->next=NULL;
returntrue;
}
boolDestroyQueue(LinkQueue&Q)
{
while(Q.front)
{
Q.rear=Q.front->next;
free(Q.front);
Q.front=Q.rear;
}
returntrue;
}
boolEnQueue(LinkQueue&Q,ElemTypedata)
{
QueuePtrp;
p=(QueuePtr)malloc(sizeof(QNode));
if(!
p)returnfalse;
p->data=data;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
returntrue;
}
boolDeQueue(LinkQueue&Q,ElemType&data)
{
QueuePtrp;
if(Q.front==Q.rear)returnfalse;
p=Q.front->next;
data=p->data;
Q.front->next=p->next;
if(Q.rear==p)Q.rear=Q.front;
free(p);
returntrue;
}
boolGetQueueTop(LinkQueueQ,ElemType&data)
{
if(Q.front==Q.rear)returnfalse;
data=(Q.front->next)->data;
returntrue;
}
boolQueueEmpty(LinkQueue&Q)
{
if(Q.front==Q.rear)returntrue;
returnfalse;
}
voidInitiateGraph(ALGraph*G)
{
inti;
G->vexnum=0;
G->arcnum=0;
for(i=0;i{
G->vertices[i].firstarc=NULL;
}
}
/**********************在图G中第i个位置增添新顶点v*****************/
voidInsertVex(ALGraph*G,inti,VertexTypev)
{
if(i>=0&&i{
G->vertices[i].data=v;//存储顶点数据元素vextex
G->vexnum++;//个数加1
}
else
printf("顶点越界\n");
}
/***************************在图G中删除v*************************/
StatusDeleteVex(ALGraph&G,intv)
{//(事实上只是释放V-1处的空间并对v-1.data=-2做标记)
inti=0;
ArcNode*p,*q;
for(i=0;i{
if(i==v)continue;
if(G.vertices[i].firstarc==NULL)continue;
if(G.vertices[i].firstarc->adjvex==v)
//如果v为该节点的第一个临界弧所指向的顶点位置
{
p=G.vertices[i].firstarc;
G.vertices[i].firstarc=p->nextarc;
free(p);
G.arcnum--;
}
else
{//q用来记录前一个弧,p为当前弧
for(p=G.vertices[i].firstarc;p!
=NULL;q=p,p=p->nextarc)
{
if(p->adjvex==v)
{
q->nextarc=p->nextarc;
free(p);
G.arcnum--;
break;//弧只有一条所以用break跳出
}
}
}
}
//*********************删除以v为弧尾的边***************
if(G.vertices[v].firstarc!
=NULL)
{
p=G.vertices[v].firstarc;
//p记录前一个弧
q=p->nextarc;
//q为当前弧
//G.vertices[v].firstarc=NULL;
while
(1)
{
free(p);
G.arcnum--;
if(q==NULL)
{
break;
}
else
{
p=q;
q=q->nextarc;
}
}
}
/*********************从数组中删除v节点**************************/
for(i=v;iG.vertices[i]=G.vertices[i+1];
G.vexnum--;
returnOK;
}
voidConnect(ALGraph&G,intv,intw)
{
ArcNode*p,*q;
if(G.vertices[v].firstarc==NULL)
{//如果是第一个节点为NULL,则直接建立
p=(ArcNode*)malloc(sizeof(ArcNode));
p->adjvex=w;
p->nextarc=NULL;
G.vertices[v].firstarc=p;
}
else
{//如果不是NULL则进行遍历到最后一个弧
for(p=G.vertices[v].firstarc;p!
=NULL;q=p,p=p->nextarc);
p=(ArcNode*)malloc(sizeof(ArcNode));
p->adjvex=w;
p->nextarc=NULL;
q->nextarc=p;
}
}
/*****在G中增添弧,若G是无向的,则还增添对称弧*******/
intInsertArc(ALGraph&G,intv,intw)
{
if(v<0||v>=G.vexnum||w<0||w>=G.vexnum)
{
printf("参数错误\n");
return0;
}
else
{
Connect(G,v,w);
G.arcnum++;
if(G.kind==1)
{//如果是无向图则反向插入一个弧
Connect(G,w,v);
G.arcnum++;
}
printf("添加弧成功\n");
return1;
}
}
/*******************删除节点v和w间的弧***********************************/
StatusDelete(ALGraph&G,intv,intw)
{
ArcNode*p,*q;
if(G.vertices[v].firstarc->adjvex==(w))
//该弧是第一条依附顶点v的弧
{
p=G.vertices[v].firstarc;
G.vertices[v].firstarc=p->nextarc;
free(p);
G.arcnum--;
returnOK;
}
else
{
//否则遍历找到这条弧
for(p=G.vertices[v].firstarc;(p->adjvex!
=w)&&(p->nextarc!
=NULL);q=p,p=p->nextarc);
if(p->adjvex==w)
{
q->nextarc=p->nextarc;
free(p);
G.arcnum--;
returnERROR;
}
else
printf("该弧不存在");returnOK;
}
}
/*****在G中删除弧,若G是无向的,则还删除对称弧*******/
StatusDeleteArc(ALGraph&G,intv,intw)
{
if(v<0||v>G.arcnum||w<0||w>G.arcnum)
{
printf("参数错误");
returnERROR;
}
else
{
Delete(G,v,w);
if(G.kind==1)
{
Delete(G,w,v);
}
returnOK;
}
}
/***********若G中存在顶点u,则返回该顶点在图中位置;否//则返回其它信息*******/
intLocateVex(ALGraphG,intu)
{
inti=0;
while((G.vertices[i].data!
=u)&&(i//遍历数组G.vertices[]查找u
i++;
if(G.vertices[i].data==u)
returni;
else
returnERROR;
}
/***********返回v的值*******************************/
intGetVex(ALGraphG,intv)
{
if(v<0||v>G.arcnum)
{
printf("参数错误");
returnERROR;
}
else
returnG.vertices[v].data;
}
//**********对v赋值value*******************************
StatusSetVex(ALGraph&G,intv,intval)
{
if(v<0||v>G.arcnum)
{
printf("参数错误");
returnERROR;
}
else
{
G.vertices[v].data=val;
returnOK;
}
}
//******返回v的第一个邻接点。
若该顶点在G中没有邻//接点,//则返回-1******
intFirstAdjVex(ALGraphG,intv)
{
if(v<0||v>G.arcnum)
{
printf("参数错误");
returnERROR;
}
else
{
if(G.vertices[v].firstarc!
=NULL)
returnG.vertices[v].firstarc->adjvex;
else
{
//printf("来自FirstAdjVex函数:
顶点:
%d没有邻接顶点\n",v);
returnerror;
}
}
}
//返回v的(相对于w的)下一个邻接点。
若w是v的最后一个邻接点,则返回"空"。
**
intNextAdjVex(ALGraph&G,intv,intw)
{
ArcNode*p;
if(v>G.vexnum||w>G.vexnum)
returnErrorInput;//输入值不正确返回-2
p=G.vertices[v].firstarc;
while(p!
=NULL)
{
if(p->adjvex!
=w)
{
p=p->nextarc;
continue;
}
else
break;
}
if(p==NULL)
{
//printf("w不是v的邻接顶点");
returnerror;
}
else
{
if(p->nextarc!
=NULL)
return(p->nextarc->adjvex);
else
{
//printf("v邻接顶点w的下一个邻接顶点不存在");
returnerror;
}
}
}
//**************创建图函数**************************
StatusCreateALG(ALGraph&G)
{
ALGraph*Gpointer=&G;
inti=0;
intout,in;
printf("请输入顶点(Vex)个数:
");
scanf("%d",&VEXNUM);
//G.vexcount=G.vexnum;
printf("请输入弧(Arc)数:
");
scanf("%d",&ARCNUM);
printf("请输入图的类型(0-有向图,1-无向图):
");
scanf("%d",&G.kind);
InitiateGraph(Gpointer);
//int*intarray=newint[G.vexnum];
for(i=0;i{
InsertVex(Gpointer,i,i+1);
//G.vertices[i].data=i+1;
//G.vertices[i].firstarc=NULL;
}
for(i=0;i{
printf("请输入弧(outint):
");
scanf("%d%d",&out,&in);
if(!
InsertArc(G,out,in))
{
i--;
}
}
//if(G.kind==1)G.arcnum*=2;
returnOK;
}
//**************从顶点v起深度优先遍历图G**************
boolvisited[20];
voidDFS(ALGraphG,intv)
{
intw;
visited[v]=true;//访问第v个顶点
printf("%d\t%d\n",v,G.vertices[v].data);
for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w))
{
if(!
visited[w])DFS(G,w);//对v的为访问的邻接顶点w递归调用DFS
}
}
voidDFSTraverse(ALGraphG)
{
for(i=0;i{
if(G.vertices[i].data<0)
{
visited[i]=true;
}
visited[i]=false;
}
printf("位置\t数据\t\n");
for(i=0;i{
if(!
visited[i])DFS(G,i);
}
}
//****************从顶点v起广度优先遍历图G***********
voidBFSTraverse(ALGraphG)
{
intw=0;
for(i=0;i{
if(G.vertices[i].data<0)
{
visited[i]=true;
}
visited[i]=false;
}
LinkQueueQ;
InitQueue(Q);
printf("位置\t数据\t\n");
for(i=0;i{
if(!
visited[i])
{
visited[i]=true;
printf("%d\t%d\n",i,G.vertices[i].data);
EnQueue(Q,i);
while(!
QueueEmpty(Q))
{
DeQueue(Q,i);
for(w=FirstAdjVex(G,i);w>=0;w=NextAdjVex(G,i,w))
{
if(!
visited[w])
{
visited[w]=true;
printf("%d\t%d\n",w,G.vertices[w].data);
EnQueue(Q,w);
}
}
}
}
}
DestroyQueue(Q);
}
StatusDestroyGraph(ALGraph&G)
{
intv=0;
for(v=0;v{
DeleteVex(G,v+1);
}
returnOK;
}
StatusPrintGraph(ALGraphG)
{
ArcNode*p;
inti=0;
printf("位置\t数据\t顶点");
for(i=0;i{
if(G.vertices[i].data<0)
{
continue;
}
printf("%d\t",i);
printf("%d\t",G.vertices[i].data);
if(G.vertices[i].firstarc!
=NULL)
{
for(p=G.vertices[i].firstarc;p!
=NULL;p=p->nextarc)
{
printf("%d\t",p->adjvex);
}
}
printf("\n");
}
returnOK;
}
voidmain()
{
intv,w,next;
ALGraphG;ALGraph*Gpointer=&G;
puts("---------建立图-----------");
CreateALG(G);
PrintGraph(G);
printf("执行退出操作请输入0\n");
printf("执行插入顶点操作请输入1\n");
printf("执行删除顶点操作请输入2\n");
printf("执行插入弧操作请输入3\n");
printf("执行删除弧操作请输入4\n");
printf("执行查找顶点位置操作请输入5\n");
printf("执行查找某位置顶点的值操作请输入6\n");
printf("执行对某顶点赋值操作请输入7\n");
printf("执行返回v的第一个邻接点操作请输入8\n");
printf("执行返回v的(相对于w的)下一个邻接点,请输入零度摆渡KingEasternSun9\n");
printf("执行从顶点v起深度优先遍历图操作请输入10\n");
printf("执行从顶点v起广度优先遍历图操作请输入11\n");
printf("请输入命令:
");
scanf("%d",&CHIOCE);
while(CHIOCE!
=0)
{
switch(CHIOCE)
{
case1:
//插入顶点
printf("请输入要插入顶点的值\n");
scanf("%d",&v);
InsertVex(Gpointer,G.vexnum,v);
PrintGraph(G);
printf("+++++++++++++++++++++++++++++++++\n");break;
case2:
//删除顶点
printf("请输入要删除顶点的位置\n");
scanf("%d",&v);
DeleteVex(G,v);
PrintGraph(G);
printf("+++++++++++++++++++++++++++++++++\n");break;
case3:
printf("请输入要插入弧的两端顶点顶点\n");
printf("请输入弧outint):
");