关于有向图的邻接表的创建,深度遍历及广度遍历.

本程序在VC环境中运行。

首先是头文件(tbl.h文件)。关于图的邻接表的定义。

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>


#define N 10
#define INFINITY  32768
#define True 1
#define False 0
#define Error -1
#define Ok 1


typedef enum{DG,DN,UDG,UDN}GraphKind;
typedef char VertexType;


//边结点
typedef struct ArcNode{
int adjVex;
struct ArcNode *nextArc;
}ArcNode;


//表结点
typedef struct VexNode{
VertexType data;
ArcNode *firstArc;
}VexNode;


//邻接表
typedef struct{
VexNode vexs[N];
int vexnum,arcnum;
GraphKind kind;
}AdjList;


//队列结点
typedef struct Node{
int data;
struct Node *next;
}Node;


//队列
typedef struct{
Node *front;
Node *rear;
}LinkQueue;


接下来是tbl.cpp文件。

#include "tbl.h"


int Dvisited[N]={0};
int Bvisited[N]={0};


//队列的初始化
int InitLinkQueue(LinkQueue &Q){
Q.front=(Node *)malloc(sizeof(Node));
if(Q.front!=NULL){//队列不为空
Q.rear=Q.front;
Q.front->next=NULL;

return True;
}else{
return False;
}
}


//进队操作
int EnterQueue(LinkQueue &Q,int x){
Node *newNode=(Node *)malloc(sizeof(Node));
newNode->data=x;
newNode->next=NULL;

Q.rear->next=newNode;
Q.rear=newNode;

return True;
}


//出队操作
int ExitQueue(LinkQueue &Q,int *x){
if(Q.front==Q.rear){
return False;
}else{
Node *p=Q.front->next;
Q.front->next=p->next;

if(Q.rear==p){
Q.rear=Q.front;
}

*x=p->data;
free(p);

return True;
}
}


//判断队列是否为空
int IsEmpty(LinkQueue Q){
if(Q.front==Q.rear){
return True;
}else{
return False;
}
}


//查找顶点所在的位置
int LocateVex(AdjList G,VertexType v){
int i,j=Error;

for(i=0;i<G.vexnum;i++){
if(G.vexs[i].data==v){
return i;
}
}

return j;
}


//创建邻接表
void CreateAdjList(AdjList &G){
int i,j,l,m;
VertexType data;

VertexType v1,v2;
printf("请输入有向图的顶点数:");
scanf("%d",&G.vexnum);

printf("\n");

printf("请输入有向图的弧数:");
scanf("%d",&G.arcnum);

printf("\n");

printf("请依次输入有向图的各个顶点:\n");

for(i=0;i<G.vexnum;i++){//初始化顶点(表结点)
printf("第%d个顶点是:",i+1);
data=getche();

printf("\n");

G.vexs[i].data=data;
G.vexs[i].firstArc=NULL;
}

for(j=0;j<G.arcnum;j++){
printf("\n请输入有向图第%d条弧的弧尾和弧头:\n",j+1);
printf("弧尾:");
v1=getche();

printf("\t");

printf("弧头:");
v2=getche();

l=LocateVex(G,v1);
m=LocateVex(G,v2);

//开辟一个新的边结点的空间
ArcNode *p=(ArcNode *)malloc(sizeof(ArcNode));
//初始化新创建的边结点
p->adjVex=m;
p->nextArc=G.vexs[l].firstArc;
G.vexs[l].firstArc=p;
}

printf("\n");
printf("有向图的邻接表创建成功。\n");
}


//显示图的信息
void Display(AdjList G){
int i;
ArcNode *p;

printf("有向图有%d个顶点,%d条弧。\n",G.vexnum,G.arcnum);

for(i=0;i<G.vexnum;i++){
p=G.vexs[i].firstArc;

while(p){
printf("<%c->%c>\t",G.vexs[i].data,G.vexs[p->adjVex].data);
p=p->nextArc;
}

printf("\n");

}
}


//深度遍历(邻接表)
void Depth(AdjList G,int adj){

ArcNode *p;

printf("%c",G.vexs[adj].data);

Dvisited[adj]=1;

p=G.vexs[adj].firstArc;

while(p!=NULL){

if(!Dvisited[p->adjVex]){


Depth(G,p->adjVex);
}

p=p->nextArc;
}
}


//广度遍历(邻接表)
void Breadth(AdjList G,int adj){
int x;

LinkQueue Q;
InitLinkQueue(Q);


Bvisited[adj]=1;
EnterQueue(Q,adj);

while(!IsEmpty(Q)){
ExitQueue(Q,&x);


printf("%c",G.vexs[x].data);

ArcNode *p=G.vexs[x].firstArc;

while(p){
if(!Bvisited[p->adjVex]){
Bvisited[p->adjVex]=1;
EnterQueue(Q,p->adjVex);
}
p=p->nextArc;
}
}
}


void main(){
AdjList G;

CreateAdjList(G);
Display(G);

printf("有向图深度遍历:");
Depth(G,0);
printf("\n");

printf("有向图广度遍历:");
Breadth(G,0);
printf("\n");
}


运行结果如下所示:

请输入有向图的顶点数:6


请输入有向图的弧数:6


请依次输入有向图的各个顶点:
第1个顶点是:a
第2个顶点是:b
第3个顶点是:c
第4个顶点是:d
第5个顶点是:e
第6个顶点是:f


请输入有向图第1条弧的弧尾和弧头:
弧尾:a  弧头:b
请输入有向图第2条弧的弧尾和弧头:
弧尾:a  弧头:c
请输入有向图第3条弧的弧尾和弧头:
弧尾:a  弧头:d
请输入有向图第4条弧的弧尾和弧头:
弧尾:b  弧头:c
请输入有向图第5条弧的弧尾和弧头:
弧尾:b  弧头:e
请输入有向图第6条弧的弧尾和弧头:
弧尾:c  弧头:f
有向图的邻接表创建成功。
有向图有6个顶点,6条弧。
<a->d>  <a->c>  <a->b>
<b->e>  <b->c>
<c->f>






有向图深度遍历:adcfbe
有向图广度遍历:adcbfe
Press any key to continue

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
有向图邻接表和无向图的邻接表类似,只是边表结点需要记录边的方向。下面是C语言有向图邻接表的输出及广度遍历的示例代码: ```c #include <stdio.h> #include <stdlib.h> #define MAX_VERTEX_NUM 100 // 最大顶点数 // 边表结点 typedef struct ArcNode { int adjvex; // 邻接点下标 struct ArcNode *next; // 指向下一个邻接点的指针 } ArcNode; // 顶点表结点 typedef struct { int data; // 顶点的数据 ArcNode *firstarc; // 指向第一个邻接点的指针 } VNode, AdjList[MAX_VERTEX_NUM]; // 邻接表结构体 typedef struct { AdjList vertices; // 顶点表 int vexnum, arcnum; // 顶点数和边数 } ALGraph; // 初始化邻接表 void InitGraph(ALGraph *G) { int i; G->vexnum = 0; G->arcnum = 0; for (i = 0; i < MAX_VERTEX_NUM; i++) { G->vertices[i].firstarc = NULL; } } // 添加边 void AddArc(ALGraph *G, int v, int w) { ArcNode *p; p = (ArcNode *)malloc(sizeof(ArcNode)); p->adjvex = w; p->next = G->vertices[v].firstarc; G->vertices[v].firstarc = p; G->arcnum++; } // 输出邻接表 void PrintGraph(ALGraph *G) { int i; ArcNode *p; for (i = 0; i < G->vexnum; i++) { printf("%d: ", G->vertices[i].data); p = G->vertices[i].firstarc; while (p != NULL) { printf("%d ", G->vertices[p->adjvex].data); p = p->next; } printf("\n"); } } // 广度优先遍历 void BFS(ALGraph *G, int v) { int visited[MAX_VERTEX_NUM] = {0}; // 记录每个顶点是否被访问过 int queue[MAX_VERTEX_NUM]; // 队列 int front = 0, rear = 0; ArcNode *p; visited[v] = 1; queue[rear++] = v; while (front < rear) { int u = queue[front++]; // 出队 printf("%d ", G->vertices[u].data); p = G->vertices[u].firstarc; while (p != NULL) { int w = p->adjvex; if (!visited[w]) { visited[w] = 1; queue[rear++] = w; // 入队 } p = p->next; } } } int main() { ALGraph G; InitGraph(&G); G.vexnum = 5; G.arcnum = 7; G.vertices[0].data = 0; G.vertices[1].data = 1; G.vertices[2].data = 2; G.vertices[3].data = 3; G.vertices[4].data = 4; AddArc(&G, 0, 1); AddArc(&G, 0, 2); AddArc(&G, 1, 2); AddArc(&G, 2, 0); AddArc(&G, 2, 3); AddArc(&G, 3, 3); AddArc(&G, 4, 3); printf("邻接表:\n"); PrintGraph(&G); printf("广度遍历:\n"); BFS(&G, 2); printf("\n"); return 0; } ``` 示例代码中的邻接表和无向图邻接表的定义和添加边的方法相同,区别在于有向图的边是有方向的,需要在添加边的时候指定边的起点和终点。在输出邻接表广度遍历时,也需要考虑边的方向。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值