注:若有错误或需要改进的地方,或有需要补充的内容请告之,新手上路,谢谢。有些函数还是比较冗余的,慢慢改进。
头文件:
/*使用栈和队列要用指针*/
/************结构体************/
/*队列*/
typedef struct qnode
{
void* data;
struct qnode *next;
}qnode;
typedef struct
{
qnode *front_,*rear;
}linkqueue;
/*栈*/
typedef struct node
{
void* data;
struct node *next;
}stacknode,*pstacknode;
typedef struct linkstac
{
stacknode *base;
stacknode *top;
}linkstack,*plinkstack;
/*************队列操作************/
/*队列初始化*/
linkqueue *init_queue()
{
linkqueue *q;
q=(linkqueue*)malloc((sizeof(linkqueue)));
q->front_=(qnode*)malloc(sizeof(qnode));
q->front_->next=NULL; //带对头结点
q->rear=q->front_;
return q;
}
/*判断队空*/
bool isempty_queue(linkqueue q)
{
if(q.front_==q.rear)
{
return true;
}
else
{
return false;
}
}
/*入队*/
void enqueue(linkqueue *q,void* e)
{
qnode *s;
s=(qnode*)malloc(sizeof(qnode));
s->data=e;
s->next=NULL;
q->rear->next=s;
q->rear=s;
}
/*出队*/
void dequeue(linkqueue *q,void* e)
{
if(q->front_==q->rear)
{
printf("队空");
}
else
{
qnode *s;
s=(qnode*)malloc(sizeof(qnode));
s=q->front_->next;
e=s->data;
q->front_->next=s->next;
if(q->rear==s) //只有一个元素
{
q->rear=q->front_;
}
free(s);
}
}
/*******************栈的操作********************/
/*链式栈初始化*/
linkstack *init_stack()
{
linkstack *s;
s=(linkstack*)malloc(sizeof(linkstack));
s->base=(stacknode*)malloc(sizeof(stacknode));
s->top=s->base;
s->base->next=NULL;
return s;
}
/*判断链式栈空*/
bool isempty_stack(linkstack *s)
{
if(s->base==s->top)
{
return true;
}
else
{
return false;
}
}
/*入栈*/
void push(linkstack *s,void* e)
{
stacknode *p;
p=(stacknode*)malloc(sizeof(stacknode));
p->data=e;
p->next=s->top;
s->top=p;
}
/*出栈*/
void pop(linkstack *s,void* &e)
{
if(s->top==s->base)
{
printf("栈空");
}
else
{
stacknode *p=s->top;
e=p->data;
s->top=p->next;
free(p);
}
}
/*链式栈的长度*/
int length(linkstack *s)
{
stacknode *p=s->top;
int i=0;
while(p!=s->base)
{
i++;
p=p->next;
}
return i;
}
/*返回栈顶元素*/
void stack_get_top(linkstack *s,void* e)
{
if(s->base==s->top)
{
printf("栈空");
}
else
{
e=s->top->data;
}
}
图的代码:
#include<stdio.h>
#include<stdlib.h>
#include<string>
#include<cstring>
#include<math.h>
#include<algorithm>
#include<ctype.h>
#include"../../头文件/link_stack_queue.h"
using namespace std;
#define MAXSIZE 100
bool visited[MAXSIZE];
typedef enum
{
NN,
NY,
YN,
YY
}AlGraph_type;
/*******************结构体*********************/
/*邻接表*/
typedef struct ArcNode //边表结点
{
int adjvex; //弧头结点的编号
struct ArcNode *nextarc;
int info; //有权图为边权值,无权图为0
}ArcNode;
typedef struct //顶点表结点
{
char data; //结点值
ArcNode *firstarc; //该顶点的第一条弧
}VNode,AdjList[MAXSIZE];
typedef struct
{
AdjList vextable;
int vexnum,arcnum;
int AlGraph_type;
}AlGraph;
/*******************对图操作的预先函数*********************/
/*判断结点是否在图中*/
bool if_vex_in(AlGraph a,char e)
{
int i;
for(i=0;i<a.vexnum;i++)
{
if(a.vextable[i].data==e)
{
return true;
}
}
return false;
}
/*返回结点在顶点表中的编号*/
int return_vex(AlGraph a,char e)
{
int i;
for(i=0;i<a.vexnum;i++)
{
if(a.vextable[i].data==e)
{
return i;
}
}
return -1;
}
/*返回某一结点的出度*/
int return_vex_outnum(AlGraph a,char e)
{
int i=0,n;
if(!if_vex_in(a,e))
{
printf("该结点不在图中\n");
return -1;
}
n=return_vex(a,e);
ArcNode *r=a.vextable[n].firstarc;
while(r!=NULL)
{
r=r->nextarc;
i++;
}
return i;
}
/*输出图*/
void print_AlGraph(AlGraph a)
{
int i,n,j;
ArcNode *p;
printf("该图的邻接表为:\n");
printf(" 顶点表 边结点(ajdvex,info)\n");
for(i=0;i<a.vexnum;i++)
{
printf(" %d | %c |-->",i,a.vextable[i].data);
n=return_vex_outnum(a,a.vextable[i].data);
p=a.vextable[i].firstarc;
for(j=0;j<n;j++)
{
printf("| %d |",p->adjvex);
if(a.AlGraph_type==2||a.AlGraph_type==4)
{
printf(" %d |",p->info);
}
printf("-->");
p=p->nextarc;
}
printf("NULL\n");
}
printf("图的结点数为%d,边数为%d\n",a.vexnum,a.arcnum);
}
/*初始化图*/
AlGraph *init_AlGraph()
{
AlGraph *a;
int i;
a=(AlGraph*)malloc(sizeof(AlGraph));
a->arcnum=a->vexnum=0;
printf("请选择图的类型 1、无向图 2、无向网 3、有向图 4、有向网:");
fflush(stdin);
scanf("%d",&i);
a->AlGraph_type=i;
fflush(stdin);
memset(a->vextable,'#',sizeof(a->vextable)); //初始顶点表由#填充
for(i=0;i<MAXSIZE;i++)
{
a->vextable[i].firstarc=(ArcNode*)malloc(sizeof(ArcNode));
a->vextable[i].firstarc=NULL;
}
return a;
}
/*判断创建的边是否已存在*/
bool if_arc_in(AlGraph a,int xn,int yn) //xn,yn为头尾结点的编号
{
int i;
ArcNode *r;
for(i=0,r=a.vextable[xn].firstarc;i<return_vex_outnum(a,a.vextable[xn].data);r=r->nextarc,i++)
{
if(r->adjvex==yn)
{
return true;
}
}
return false;
}
/*******************无向图*********************/
/*构建图*/
void create_AlGraph_NN(AlGraph *a)
{
int V,E,i,xn,yn;
char x,y;
ArcNode *p1,*p2;
printf("构建无向图\n请输入结点数与边数:");
scanf("%d %d",&V,&E);
printf("请输入头尾结点:\n");
for(i=0;i<E;i++)
{
fflush(stdin);
scanf("%c %c",&x,&y);
fflush(stdin);
if(!if_vex_in(*a,x))
{
(a->vextable[a->vexnum++].data)=x;
}
if(!if_vex_in(*a,y))
{
(a->vextable[a->vexnum++].data)=y;
}
xn=return_vex(*a,x);
yn=return_vex(*a,y);
if(if_arc_in(*a,xn,yn)||if_arc_in(*a,yn,xn))
{
continue;
}
p1=(ArcNode*)malloc(sizeof(ArcNode));
p1->info=0;
p1->adjvex=yn;
p1->nextarc=a->vextable[xn].firstarc;
a->vextable[xn].firstarc=p1;
p2=(ArcNode*)malloc(sizeof(ArcNode));
p2->info=0;
p2->adjvex=xn;
p2->nextarc=a->vextable[yn].firstarc;
a->vextable[yn].firstarc=p2;
a->arcnum++;
}
}
/*******************有向图*********************/
/*构建图*/
void create_AlGraph_YN(AlGraph *a)
{
int V,E,i,xn,yn;
char x,y;
ArcNode *p1;
printf("构建有向图\n请输入结点数与边数:");
scanf("%d %d",&V,&E);
printf("请输入头尾结点:\n");
for(i=0;i<E;i++)
{
fflush(stdin);
scanf("%c %c",&x,&y);
fflush(stdin);
if(!if_vex_in(*a,x))
{
(a->vextable[a->vexnum++].data)=x;
}
if(!if_vex_in(*a,y))
{
(a->vextable[a->vexnum++].data)=y;
}
xn=return_vex(*a,x);
yn=return_vex(*a,y);
if(if_arc_in(*a,xn,yn))
{
continue;
}
p1=(ArcNode*)malloc(sizeof(ArcNode));
p1->adjvex=yn;
p1->info=0;
p1->nextarc=a->vextable[xn].firstarc;
a->vextable[xn].firstarc=p1;
a->arcnum++;
}
}
/*******************无向网*********************/
/*构建图*/
void create_AlGraph_NY(AlGraph *a)
{
int V,E,i,c,xn,yn;
char x,y;
ArcNode *p1,*p2;
printf("构建无向网\n请输入结点数与边数:");
scanf("%d %d",&V,&E);
printf("请输入头尾结点与权值:\n");
for(i=0;i<E;i++)
{
fflush(stdin);
scanf("%c %c %d",&x,&y,&c);
fflush(stdin);
if(!if_vex_in(*a,x))
{
(a->vextable[a->vexnum++].data)=x;
}
if(!if_vex_in(*a,y))
{
(a->vextable[a->vexnum++].data)=y;
}
xn=return_vex(*a,x);
yn=return_vex(*a,y);
if(if_arc_in(*a,xn,yn)||if_arc_in(*a,yn,xn))
{
continue;
}
p1=(ArcNode*)malloc(sizeof(ArcNode));
p1->info=c;
p1->adjvex=yn;
p1->nextarc=a->vextable[xn].firstarc;
a->vextable[xn].firstarc=p1;
p2=(ArcNode*)malloc(sizeof(ArcNode));
p2->info=c;
p2->adjvex=xn;
p2->nextarc=a->vextable[yn].firstarc;
a->vextable[yn].firstarc=p2;
a->arcnum++;
}
}
/*******************有向网*********************/
/*构建图*/
void create_AlGraph_YY(AlGraph *a)
{
int V,E,i,xn,yn,c;
char x,y;
ArcNode *p1;
printf("构建有向网\n请输入结点数与边数:");
scanf("%d %d",&V,&E);
printf("请输入头尾结点与权值:\n");
for(i=0;i<E;i++)
{
fflush(stdin);
scanf("%c %c %d",&x,&y,&c);
fflush(stdin);
if(!if_vex_in(*a,x))
{
(a->vextable[a->vexnum++].data)=x;
}
if(!if_vex_in(*a,y))
{
(a->vextable[a->vexnum++].data)=y;
}
xn=return_vex(*a,x);
yn=return_vex(*a,y);
if(if_arc_in(*a,xn,yn))
{
continue;
}
p1=(ArcNode*)malloc(sizeof(ArcNode));
p1->adjvex=yn;
p1->info=c;
p1->nextarc=a->vextable[xn].firstarc;
a->vextable[xn].firstarc=p1;
a->arcnum++;
}
}
/*******************对图操作*********************/
/*创建图*/
AlGraph *create_AlGraph()
{
AlGraph *a;
a=init_AlGraph();
switch (a->AlGraph_type)
{
case 1:create_AlGraph_NN(a);break;
case 2:create_AlGraph_NY(a);break;
case 3:create_AlGraph_YN(a);break;
case 4:create_AlGraph_YY(a);break;
}
return a;
}
/*初始化visited[]*/
void init_visited(AlGraph a)
{
int i;
for(i=0;i<a.vexnum;i++)
{
visited[i]=false; //false为未访问
}
for(i=a.vexnum;i<MAXSIZE;i++)
{
visited[i]=true;
}
}
/*深度优先遍历*/
void DFS(AlGraph a,int n) //n为结点的编号
{
int i;
ArcNode *r;
printf("%c",a.vextable[n].data);
visited[n]=true;
for(r=a.vextable[n].firstarc,i=0;i<return_vex_outnum(a,a.vextable[n].data);i++,r=r->nextarc)
{
if(!visited[r->adjvex])
{
DFS(a,r->adjvex);
}
}
}
void DFSTraverse(AlGraph a)
{
printf("该图的深度优先遍历为:");
int i;
init_visited(a);
for(i=0;i<a.vexnum;i++)
{
if(!visited[i])
{
DFS(a,i);
}
}
printf("\n");
}
/*广度优先遍历*/
void BFS(AlGraph a,int *n) //n为结点的编号
{
int i;
ArcNode *r;
linkqueue *q;
q=init_queue();
printf("%c",a.vextable[*n].data);
visited[*n]=true;
enqueue(q,n);
while(!isempty_queue(*q))
{
dequeue(q,n);
for(r=a.vextable[*n].firstarc,i=0;i<return_vex_outnum(a,a.vextable[*n].data);r=r->nextarc,i++)
{
if(!visited[r->adjvex])
{
printf("%c",a.vextable[r->adjvex].data);
visited[r->adjvex]=true;
enqueue(q,&(r->adjvex));
}
}
}
}
void BFSTraverse(AlGraph a)
{
printf("该图的广度优先遍历为:");
int i;
init_visited(a);
for(i=0;i<a.vexnum;i++)
{
if(!visited[i])
{
BFS(a,&i);
}
}
printf("\n");
}
/*插入一条弧*/
void insert_arc(AlGraph *a,char x,char y,int c)
{
if(!if_vex_in(*a,x)||!if_vex_in(*a,y))
{
printf("插入的弧的结点不存在\n");
return ;
}
int xn,yn;
xn=return_vex(*a,x);
yn=return_vex(*a,y);
if(a->AlGraph_type==1||a->AlGraph_type==2) //NN NY
{
if(if_arc_in(*a,xn,yn)||if_arc_in(*a,yn,xn))
{
printf("要插入的弧已存在\n");
return ;
}
if(a->AlGraph_type==1) //NN
{
ArcNode *r1;
r1=(ArcNode*)malloc(sizeof(ArcNode));
r1->adjvex=yn;
r1->nextarc=a->vextable[xn].firstarc;
a->vextable[xn].firstarc=r1;
ArcNode *r2;
r2=(ArcNode*)malloc(sizeof(ArcNode));
r2->adjvex=xn;
r2->nextarc=a->vextable[yn].firstarc;
a->vextable[yn].firstarc=r2;
a->arcnum++;
}
else
{
ArcNode *r1;
r1=(ArcNode*)malloc(sizeof(ArcNode));
r1->adjvex=yn;
r1->info=c;
r1->nextarc=a->vextable[xn].firstarc;
a->vextable[xn].firstarc=r1;
ArcNode *r2;
r2=(ArcNode*)malloc(sizeof(ArcNode));
r2->adjvex=xn;
r2->info=c;
r2->nextarc=a->vextable[yn].firstarc;
a->vextable[yn].firstarc=r2;
a->arcnum++;
}
}
else
{
if(if_arc_in(*a,xn,yn))
{
printf("要插入的结点已存在\n");
return ;
}
if(a->AlGraph_type==3) //YN
{
ArcNode *r;
r=(ArcNode*)malloc(sizeof(ArcNode));
r->adjvex=yn;
r->nextarc=a->vextable[xn].firstarc;
a->vextable[xn].firstarc=r;
a->arcnum++;
}
else
{
ArcNode *r;
r=(ArcNode*)malloc(sizeof(ArcNode));
r->adjvex=yn;
r->info=c;
r->nextarc=a->vextable[xn].firstarc;
a->vextable[xn].firstarc=r;
a->arcnum++;
}
}
}
/*删除一条弧*/
bool delete_arc(AlGraph *a,char x,char y)
{
int xn=return_vex(*a,x),yn=return_vex(*a,y),i;
if(!if_arc_in(*a,xn,yn))
{
printf("要删除的弧不存在\n");
return false;
}
ArcNode *r;
if(a->AlGraph_type==1||a->AlGraph_type==2) //NN NY
{
for(r=a->vextable[xn].firstarc,i=0;i<return_vex_outnum(*a,x);r=r->nextarc,i++)
{
if(i==0)
{
if(r->adjvex==yn)
{
a->vextable[xn].firstarc=r->nextarc;
a->arcnum--;
break;
}
}
if(r->nextarc->adjvex==yn)
{
ArcNode *p=r->nextarc;
r->nextarc=p->nextarc;
free(p);
a->arcnum--;
break;
}
}
for(r=a->vextable[yn].firstarc,i=0;i<return_vex_outnum(*a,y);r=r->nextarc,i++)
{
if(i==0)
{
if(r->adjvex==xn)
{
a->vextable[yn].firstarc=r->nextarc;
a->arcnum--;
return true;
}
}
if(r->nextarc->adjvex==xn)
{
ArcNode *p=r->nextarc;
r->nextarc=p->nextarc;
free(p);
a->arcnum--;
return true;
}
}
}
else
{
for(r=a->vextable[xn].firstarc,i=0;i<return_vex_outnum(*a,x);r=r->nextarc,i++)
{
if(i==0)
{
if(r->adjvex==yn)
{
a->vextable[xn].firstarc=r->nextarc;
a->arcnum--;
return true;
}
}
if(r->nextarc->adjvex==yn)
{
ArcNode *p=r->nextarc;
r->nextarc=p->nextarc;
free(p);
a->arcnum--;
return true;
}
}
}
}
/*插入一个结点*/
void insert_node(AlGraph *a)
{
printf("请输入要插入的结点:");
char x;
fflush(stdin);
scanf("%c",&x);
if(if_vex_in(*a,x))
{
printf("插入的结点已存在\n");
return ;
}
a->vextable[a->vexnum++].data=x;
//a->vextable[a->vexnum-1].firstarc=NULL; 已在初始化时全部设置为NULL
}
/*删除一个结点*/
bool delete_node(AlGraph *a)
{
printf("输入要删除的结点:");
char x;
fflush(stdin);
scanf("%c",&x);
if(!if_vex_in(*a,x))
{
printf("要删除的结点不存在\n");
return false;
}
int xn,i,j,num=0;
xn=return_vex(*a,x);
ArcNode *r;
for(i=0;i<a->vexnum;i++) //删除边
{
if(i==xn)
{
continue;
}
for(r=a->vextable[i].firstarc,j=0;j<return_vex_outnum(*a,a->vextable[i].data);r=r->nextarc,j++)
{
if(r->adjvex==xn)
{
delete_arc(a,a->vextable[i].data,x);
num++;
}
}
}
if(a->AlGraph_type==1||a->AlGraph_type==2)
{
a->arcnum+=num;
}
else
{
a->arcnum-=return_vex_outnum(*a,a->vextable[xn].data);
}
for(i=0;i<a->vexnum;i++)
{
if(i>=xn)
{
a->vextable[i].data=a->vextable[i+1].data;
a->vextable[i].firstarc=a->vextable[i+1].firstarc;
}
for(r=a->vextable[i].firstarc,j=0;j<return_vex_outnum(*a,a->vextable[i].data);r=r->nextarc,j++)
{
if(r->adjvex>xn)
{
r->adjvex--;
}
}
}
a->vexnum--;
}
int main()
{
AlGraph *a;
a=create_AlGraph();
print_AlGraph(*a);
fflush(stdin);
delete_node(a);
print_AlGraph(*a);
BFSTraverse(*a);
DFSTraverse(*a);
return 0;
}
/*
a c 3
a d 8
a b 5
c d 10
d a 7
d b 20
a c
a d
a b
c d
d a
d b
*/