实现图的创建,广度,深度遍历,拓扑排序。
#include<stdio.h>
#define MAXQSIZE 50
#define MVNum 50
#define error MVNum+10
#define OVERFLOW 0
typedef int Status;
#define OK 1
#define ERROR 0
#define null -1
#include "stdlib.h"
#include "string.h"
typedef struct arcnode{
int adjvex;
struct arcnode *nextatc;
}arcnode;
typedef struct vnode{
int data;
arcnode *firstarc;
}vnode,adjlist[MVNum];
typedef struct{
adjlist vertices; //特殊数组
int vexnum,arcnum; //顶点数,边数
}algraph;
//循环队列定义
typedef struct
{
int *base;
int front;
int rear;
} SqQueue;
//循环队列的初始化
Status InitQueue(SqQueue &Q)
{
Q.base=new int[MAXQSIZE];
if(!Q.base)
return(OVERFLOW);
Q.front=Q.rear=0;
return OK;
}
//入队
Status EnQueue(SqQueue &Q,int e)
{
if((Q.rear+1)%MAXQSIZE==Q.front)
return ERROR;
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXQSIZE;
return OK;
}
//出队
Status DeQueue(SqQueue &Q,int &e)
{
if(Q.front==Q.rear)
return ERROR;
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXQSIZE;
return OK;
}
int pankong(SqQueue Q)
{
if(Q.front==Q.rear) return 1;
return 0;
}
//栈的定义 (实数栈)
typedef struct StackNode1
{
float data;
struct StackNode1 *next;
}StackNode1,*LinkStack1;
//栈的初始化 (实数栈)
Status InitStack1(LinkStack1 &S)
{
S=NULL;
return OK;
}
//判断栈是否为空(实数栈)
int StackEmpty1(LinkStack1 S)
{
if(S==NULL)return 1;
return 0;
}
//入栈 (实数栈)
Status Push1(LinkStack1 &S,int e)
{
LinkStack1 p;
p=(LinkStack1)malloc(sizeof(StackNode1));
p->data=e;
p->next=S;
S=p;
return OK;
}
//出栈 (实数栈)
Status Pop1(LinkStack1 &S,int &e)
{
LinkStack1 p;
if(S==NULL) return ERROR;
e=S->data;
p=S;
S=S->next;
delete p;
return OK;
}
//找出节点位置
int location(algraph g,int h){
for(int i = 0;i<g.vexnum ;i++){
if(g.vertices[i].data ==h)
return i;
}
}
//创建一个邻接表
void createudg(algraph *g,algraph *s){
int ww[MVNum];
printf("请输入顶点个数:\n");
scanf("%d",&g->vexnum);
s->vexnum = g->vexnum ;
printf("请输入边数:\n");
scanf("%d",&g->arcnum);
s->arcnum = g->arcnum ;
printf("请输入%d个顶点的值:\n",g->vexnum);
for(int i = 0;i<g->vexnum;i++){
scanf("%d",&ww[i]);}
for(int i = 0;i< g->vexnum ; i++){
g->vertices[i].data = ww[i];
s->vertices[i].data = ww[i];
g->vertices[i].firstarc = NULL;
s->vertices[i].firstarc = NULL;
}
printf("请输入各个边的两点值:\n");
for(int i=0 ; i < g->arcnum ; i++){
int j,k;
scanf("%d",&j);
scanf("%d",&k);
int w = location(*g,j);
int m = location(*g,k);
//printf("%d,%d",w,m);
arcnode *p1 = new arcnode;
p1->adjvex = m;
p1->nextatc = g->vertices[w].firstarc;
g->vertices[w].firstarc = p1;
arcnode *p2 = new arcnode;
p2->adjvex = w;
p2->nextatc = s->vertices[m].firstarc;
s->vertices[m].firstarc = p2;
}
printf("邻接表,逆邻接表创建成功。\n");
}
//深度优先搜索
void dfs_al(algraph g,int v,int a[]){
a[v] = 1;
arcnode *p1;
p1 = g.vertices[v].firstarc;
printf("%d\t",g.vertices[v].data);
while(p1!=NULL){
int w = p1->adjvex;
if(!a[w])
dfs_al(g,w,a);
p1= p1->nextatc;
}
}
//返回下一个元素
int firstadj(algraph g,int v){
int h;
arcnode *p1 = new arcnode;
p1 = g.vertices[v].firstarc;
if(p1==NULL)
return -1;
h = p1->adjvex;
return h;
}
//返回下下一个
int nextadj(algraph g,int v,int w){
arcnode *p1 = new arcnode;
arcnode *p2 = new arcnode;
p1 = g.vertices[v].firstarc;
while(1){
if(p1->nextatc==NULL)
return -1;
p2=p1->nextatc;
if(p1->adjvex == w)
return p2->adjvex;
p1=p2;
}
}
//广度优先搜索
void bfs_al(algraph g,int v,int a[]){
SqQueue S4;
int u,w;
InitQueue (S4);
a[v] = 1;
EnQueue(S4,v);
while(!pankong(S4)){
DeQueue(S4,u);
printf("%d\t",g.vertices[u].data);
for(w=firstadj(g,u);w>=0;w=nextadj(g,u,w)){
if(!a[w]){
a[w] = 1;
EnQueue(S4,w);
}
}
}
}
//确定度数
int findindeggre(algraph g,int v){
int ww=0;
arcnode *p = new arcnode;
p=g.vertices[v].firstarc;
if(p==NULL)
return 0;
while(p!=NULL){
p=p->nextatc;
ww++;
}
return ww;
}
//拓扑排序
int topolog(algraph g,algraph s,int a[]){
int indegree[MVNum],u,k;
arcnode *p = new arcnode;
for(int i = 0;i<g.vexnum;i++)
indegree[i]=findindeggre(s,i);
LinkStack1 S;
InitStack1(S);
for(int i=0;i<g.vexnum ;i++)
if(!indegree[i])
Push1(S,i);
int m=0;
while(!StackEmpty1(S)){
Pop1(S,u);
a[m]=u;
++m;
p=g.vertices[u].firstarc;
while(p!=NULL){
k=p->adjvex;
--indegree[k];
if(indegree[k]==0)
Push1(S,k);
p=p->nextatc;
}
}
if(m<g.vexnum)
return ERROR;
else
return OK;
}
void main(){
int v;
int visited[MVNum],top[MVNum];
algraph G,SS;
createudg(&G,&SS);
printf("\n----------------------------------------\n\n");
printf("\n请输入从第几个顶点开始遍历:\n");
scanf("%d",&v);
v-=1;
for(int i = 0;i<G.vexnum;i++)
visited[i]=0;
printf("深度优先遍历为:\n");
dfs_al(G,v,visited);
for(int i = 0;i<G.vexnum;i++)
visited[i]=0;
printf("\n广度优先遍历为:\n");
bfs_al(G,v,visited);
printf("\n----------------------------------------\n\n");
printf("\n拓扑排序后顺序为:\n");
int c=topolog(G,SS,top);
if(c==0)
printf("图中有回路存在\n");
else{
for(int i=0;i<G.vexnum ;i++){
int lc,ly;
lc=top[i];
ly=G.vertices[lc].data;
printf("%d\t",ly);
}
}
printf("\n----------------------------------------\n\n");
}