数据结构课设完整代码可直接运行附注释.docx
《数据结构课设完整代码可直接运行附注释.docx》由会员分享,可在线阅读,更多相关《数据结构课设完整代码可直接运行附注释.docx(34页珍藏版)》请在冰豆网上搜索。
数据结构课设完整代码可直接运行附注释
#include
#include
#include
#defineERROR0//定义字符常量error
#defineOK1//定义字符常量OK
#defineINFINITYINT_MAX//INT_MAX是系统库中定义的无穷大常量,即2个字节所能表示的最大数
#defineMAX_VERTEX_NUM21//定义图、网的最大定点数为21
#defineSTACK_INIT_SIZE100//定义栈的容量
#defineSTACKINCREAMENT10//定义栈的每次增长量
#defineMAX_INT10000//无穷大
typedefintAdjType;
typedefstruct{
intpi[MAX_VERTEX_NUM];//存放v到vi的一条最短路径
intend;
}PathType;
typedefcharVType;//设顶点为字符类型
typedefenum{DG,UDG,DN,UDN}GraphKind;//定义图、网的枚举常量
/*·················邻接矩阵····················*/
typedefstructArcCell{
intadj;//弧的权值
//infotype*info;
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedefstruct{
charvexs[MAX_VERTEX_NUM];//存储顶点的数组
AdjMatrixarcs;//存储邻接矩阵的二维数组
intvexnum,arcnum;//顶点数和弧数
GraphKindkind;//链接矩阵的类型
}MGraph;
/*·················邻接表····················*/
typedefstructArcNode{
intadjvex;//与首节点关联的顶点
intquan;//该顶点的权值
structArcNode*nextarc;//指向下一个节点的指针
}ArcNode,*AList;
typedefstructVNode{
chardata;//链表的各顶点
AListfirstarc;//链表的首节点
}VNode,AdjList[MAX_VERTEX_NUM];
typedefstruct{
AdjListvertices;//存储链接表的各顶点
intvexnum,arcnum;//顶点书和弧数
GraphKindkind;//链接表的类型
}ALGraph;
/*·················队列····················*/
typedefstructQNode{
chardata;//队列中元素数据
structQNode*next;//指向下一元素的指针
}QNode,*QueuePre;
typedefstruct{
QueuePrefront;//队首指针
QueuePrerear;//队尾指针
}LinkQueue;
/*·················栈····················*/
typedefstruct{
int*base;//栈底指针
int*top;//栈首指针
intstacksize;//栈的大小
}SqStack;
/*·················求最小生成树中的辅助数组··········*/
typedefstruct{
charadjvex;//最小生成树的节点
intlowcost;//到该节点的最小权值开销
}closedges[MAX_VERTEX_NUM];
intoption;//图的类型标识符
intvisited[MAX_VERTEX_NUM];//顶点访问标记数组
intindegree[MAX_VERTEX_NUM];//顶点入度记录数组
intve[MAX_VERTEX_NUM];//顶点权值记录数组
/*·················链接矩阵类型设置··········*/
intSetGraphKind(MGraph&G,intoption){
switch(option){
case1:
G.kind=DG;break;
case2:
G.kind=UDG;break;
case3:
G.kind=DN;break;
case4:
G.kind=UDN;break;
default:
returnERROR;
}
returnOK;
}
/*·················邻接表类型设置··········*/
intSetGraphKind(ALGraph&G,intoption){
switch(option){
case1:
G.kind=DG;break;
case2:
G.kind=UDG;break;
case3:
G.kind=DN;break;
case4:
G.kind=UDN;break;
default:
returnERROR;
}
returnOK;
}
/*·················邻接矩阵顶点定位
·················将顶点V代入,查询顶点存储数组,返回其数组下标
··········*/
intLocateVex(MGraphG,charv){
intm;
for(m=1;m<=G.vexnum;m++){
if(G.vexs[m]==v)returnm;
}
printf("您输入的顶点不存在");
returnERROR;
}
/*·················邻接表顶点定位
·················将顶点V代入,查询顶点存储数组,返回其数组下标
··········*/
intLocateVex(ALGraphG,charv){
intm;
for(m=1;m<=G.vexnum;m++){
if(G.vertices[m].data==v)returnm;
}
printf("您输入的顶点不存在");
returnERROR;
}
/*·················队列创建··········*/
intInitQueue(LinkQueue&Q){
Q.front=Q.rear=(QueuePre)malloc(sizeof(QNode));//申请存储空间,队首队尾指向同一位置
if(!
Q.front)returnERROR;
Q.front->next=NULL;
returnOK;
}
/*·················元素入队··········*/
intEnQueue(LinkQueue&Q,inte){
QueuePrep;
p=(QueuePre)malloc(sizeof(QNode));
if(!
p)returnOK;
p->data=e;p->next=NULL;
Q.rear->next=p;
Q.rear=p;
returnOK;
}
/*·················元素出队··········*/
intDeQueue(LinkQueue&Q,int&e){
QueuePrep;
if(Q.front==Q.rear)returnERROR;
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(Q.rear==p)Q.rear=Q.front;
free(p);
returnOK;
}
/*·················判断队列是否为空··········*/
intQueueEmpty(LinkQueueQ){
if(Q.front==Q.rear)
returnOK;
returnERROR;
}
/*·················栈的创建··········*/
intInitStack(SqStack&S){
S.base=(int*)malloc(STACK_INIT_SIZE*sizeof(int));
if(!
S.base)returnERROR;
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
returnOK;
}
/*·················//元素入栈··········*/
intPush(SqStack&S,inte){
if(S.top-S.base>=S.stacksize){
S.base=(int*)realloc(S.base,(S.stacksize+STACKINCREAMENT)*sizeof(int));
if(!
S.base)returnERROR;
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREAMENT;
}
*S.top++=e;
returnOK;
}
/*·················元素出栈··········*/
intPop(SqStack&S,int&e){
if(S.top==S.base)returnERROR;
e=*--S.top;
returnOK;
}
/*·················判断栈是否为空··········*/
intStackEmpty(SqStackS){
if(S.top==S.base)returnOK;
returnERROR;
}
/*·················创建邻接矩阵··········*/
intCreatGraph(MGraph&G){
inti,j,k,w;charx,y;
if(!
SetGraphKind(G,option)){printf("对图类型的设置失败");returnERROR;}//设置链接矩阵类型
printf("邻接矩阵:
请输入定点的个数、弧的个数:
");
scanf("%d%d",&G.vexnum,&G.arcnum);
if(G.vexnum>20){
printf("您输入的顶点个数超过最大值");
returnERROR;
}//if
printf("请输入%d个顶点\n",G.vexnum);
for(i=1;i<=G.vexnum;++i){//输入矩阵的各顶点
fflush(stdin);//清除缓存,略过
scanf("%c",&G.vexs[i]);
}//for
if(G.kind==DG||G.kind==UDG){//1.有向图和无向图的矩阵创建
for(i=1;i<=G.vexnum;i++)//矩阵初始化
for(j=1;j<=G.vexnum;j++)
G.arcs[i][j].adj=0;
if(G.kind==DG){//2.有向图
printf("请输入有向图的两个相邻的顶点(如果互相邻接则也要输入):
\n");
for(k=1;k<=G.arcnum;k++){//循环输入
fflush(stdin);
scanf("%c%c",&x,&y);//输入矩阵中弧关联的两顶点
i=LocateVex(G,x);j=LocateVex(G,y);//将两顶点转换成顶点存储数组的下标
G.arcs[i][j].adj=1;
}//for
}//2.if
else{//2.无向图
printf("请输入无向图的两个相邻的顶点(x,y):
\n");
for(k=1;k<=G.arcnum;k++){fflush(stdin);
scanf("%c%c",&x,&y);
i=LocateVex(G,x);j=LocateVex(G,y);
G.arcs[i][j].adj=1;G.arcs[j][i].adj=G.arcs[i][j].adj;//反向关联两顶点
}//for
}//2.else
}//1.if
else{//1.有向网和无向网
for(i=1;i<=G.vexnum;i++)
for(j=1;j<=G.vexnum;j++)
G.arcs[i][j].adj=INT_MAX;//矩阵初始化
if(G.kind==DN){//3.有向网
printf("请输入有向网的两个相邻的顶点以及相应的权值w(如果互相邻接则也要输入):
\n");
for(k=1;k<=G.arcnum;k++){fflush(stdin);
scanf("%c%c%d",&x,&y,&w);
i=LocateVex(G,x);j=LocateVex(G,y);
G.arcs[i][j].adj=w;
}//for
}//3.if
else{//3
printf("请输入无向网的两个相邻的顶点(x,y)以及相应的权值w:
\n");
for(k=1;k<=G.arcnum;k++){fflush(stdin);
scanf("%c%c%d",&x,&y,&w);
i=LocateVex(G,x);j=LocateVex(G,y);
G.arcs[i][j].adj=w;G.arcs[j][i].adj=G.arcs[i][j].adj;//逆向关联
}//for
}//3.else
}
returnOK;
}
/*··············在邻接表中插入节点·············*/
intsetList(intx,inty,ALGraph&G,intkey[]){
inti,j,m,n;AListp,q;
m=LocateVex(G,x);//获取节点x对应的数组下标
n=LocateVex(G,y);
p=G.vertices[m].firstarc;//获取第m个链表的首节点
q=(AList)malloc(sizeof(ArcNode));//申请节点空间
if(!
q)returnERROR;
q->nextarc=NULL;
q->adjvex=n;
while(key[m]&&p->nextarc){//key存储着该链表的长度,当其不为零时在首节点后插入新节点
p=p->nextarc;
key[m]++;//链表长度加1
}
if(!
key[m]){G.vertices[m].firstarc=q;key[m]++;}//当链表长度为零时,新节点为首节点
elsep->nextarc=q;
return1;
}
/*·················创建邻接表··········*/
intCreatAList(ALGraph&G){
inti,j,m,n,key[MAX_VERTEX_NUM];charx,y,w;AListp,q;
SetGraphKind(G,option);
printf("邻接表:
请输入顶点的个数和弧的个数:
");
scanf("%d%d",&G.vexnum,&G.arcnum);
if(G.vexnum>20){
printf("您输入的顶点个数超过最大值");
returnERROR;
}
printf("请输入个顶点:
\n");
for(i=1;i<=G.vexnum;i++){
fflush(stdin);
scanf("%c",&G.vertices[i].data);
G.vertices[i].firstarc=NULL;
key[i]=0;
}
if(G.kind==DG){//有向图
printf("请输入弧(如AB,其中AB与BA是不同的弧):
\n");
for(j=1;j<=G.arcnum;j++){
fflush(stdin);
scanf("%c%c",&x,&y);//输入弧的两顶点
m=LocateVex(G,x);//将两顶点转换成数组下标
n=LocateVex(G,y);
p=G.vertices[m].firstarc;//获取第m个链表的首节点,及以第m个顶点为首节点的链表
q=(AList)malloc(sizeof(ArcNode));//申请节点存储空间
if(!
q)returnERROR;
q->nextarc=NULL;
q->adjvex=n;
while(key[m]&&p->nextarc){//链表长度不为零,且下一个节点存在时,在首节点后插入新节点
p=p->nextarc;
key[m]++;
}
if(!
key[m]){G.vertices[m].firstarc=q;key[m]++;}//链表长度为零时,新节点为首节点
elsep->nextarc=q;
}
}
if(G.kind==UDG){
printf("请输入弧(如AB,其中AB与BA是不同的弧):
\n");
for(j=1;j<=G.arcnum;j++){
fflush(stdin);
scanf("%c%c",&x,&y);
setList(x,y,G,key);
setList(y,x,G,key);
}
}
if(G.kind==DN){
printf("请输入依次输入弧以及这条弧的权值(如AB8,其中AB与BA是不同的弧):
\n");
for(j=1;j<=G.arcnum;j++){
fflush(stdin);
scanf("%c%c%d",&x,&y,&w);
m=LocateVex(G,x);
n=LocateVex(G,y);
p=G.vertices[m].firstarc;
q=(AList)malloc(sizeof(ArcNode));
if(!
q)returnERROR;
q->nextarc=NULL;
q->quan=w;
q->adjvex=n;
while(key[m]&&p->nextarc){
p=p->nextarc;
key[m]++;
}
if(!
key[m]){G.vertices[m].firstarc=q;key[m]++;}
elsep->nextarc=q;
}
}
if(G.kind==UDN){
printf("无向网请输入依次输入弧以及这条弧的权值(如AB8,其中AB与BA是不同的弧):
\n");
for(j=1;j<=G.arcnum;j++){
fflush(stdin);
scanf("%c%c%d",&x,&y,&w);
m=LocateVex(G,x);
n=LocateVex(G,y);
p=G.vertices[m].firstarc;
q=(AList)malloc(sizeof(ArcNode));
if(!
q)returnERROR;
q->nextarc=NULL;
q->quan=w;
q->adjvex=n;
while(key[m]&&p->nextarc){
p=p->nextarc;
key[m]++;
}
if(!
key[m]){G.vertices[m].firstarc=q;key[m]++;}
elsep->nextarc=q;
inttemp;
temp=m;
m=n;
n=temp;
p=G.vertices[m].firstarc;
q=(AList)malloc(sizeof(ArcNode));
if(!
q)returnERROR;
q->nextarc=NULL;
q->quan=w;
q->adjvex=n;
while(key[m]&&p->nextarc){
p=p->nextarc;
key[m]++;
}
if(!
key[m]){G.vertices[m].firstarc=q;key[m]++;}
elsep->nextarc=q;
}
}
returnOK;
}
/*·················判断以第v个顶点为首节点的链表是否存在··········*/
intFirstAdjVex(ALGraphG,intv){
if(G.vertices[v].firstarc)
returnG.vertices[v].firstarc->adjvex;//存在则返回首节点
return0;
}
/*·················获取以第v个顶点为首节点的链表中的节点w的子节点··········*/
intNextAdjVex(ALGraphG,intv,intw){
ALists;
s=G.vertices[v].firstarc;//获取链表的首节点v
while(s->adjvex!
=w)//当节点不是w时,指针后移直到找到节点w或到达最后一个节点
s=s->nextarc;
if(s->nextarc)//跳出循环后,节点不为空,则表明找到了节点w,否则表示已至链表最后一个节点
returns->nextarc->adjvex;
return0;
}
/*·················遍历节点v的叶子节点··········*/
voidDFS(ALGraphG,intv){
intw;
visited[v]=1;printf("%c",G.vertices[v]);//输出第v个顶点,并标记为已访问
for(w=FirstAdjVex(G,v);w>=1;w=NextAdjVex(G,v,w)){//遍历第v个顶点的子节点,并递归遍历子节点的子节点
if(!
visited[w])DFS(G,w);