#include<stdio.h>
#include<stdlib.h>
#define MAX_VERTAX_SIZE 20
#define OK 1
#define ERROR 0
typedef int Status;
typedef char ElemType;
typedef struct EageNode{
int adjacentVertax;
struct EageNode* nextAdjacentVertax;
}EageNode, *EageNodePtr;
typedef struct VertaxNode{
ElemType data;
EageNodePtr firstEage;
}VertaxNode;
typedef struct GraphAL{
VertaxNode VertaxArray[MAX_VERTAX_SIZE];
int vertaxNum;
int eageNum;
}GraphAL;
//定义队列结构,用于图的广度优先遍历
typedef struct QueueNode{
ElemType data;
struct QueueNode* next;
}QueueNode, *QueueNodePtr;
typedef struct Queue{
QueueNodePtr front;
QueueNodePtr rear;
}Queue;
Status InitQueue(Queue* Q){
Q->front = (QueueNodePtr)malloc(sizeof(struct QueueNode));
if( !Q->front )
return ERROR;
Q->rear = Q->front;
Q->rear->next = NULL;
return OK;
}
Status EnterQueue(Queue *q, ElemType value){
QueueNode* n;
n = (QueueNode*)malloc(sizeof(struct QueueNode));
if( !n )
return ERROR;
n->data = value;
n->next = q->rear->next;
q->rear->next = n;
q->rear = n;
return OK;
}
Status DeleteQueue(Queue* q,ElemType* value){
if( q->front == q->rear )
return ERROR;
QueueNode* p;
p = q->front->next;
*value = p->data;
q->front->next = p->next;
free(p);
if( p == q->rear )
q->rear = q->front;
return OK;
}
int IsQueueEmpty(Queue q){
return q.front == q.rear ? OK : ERROR;
}
/*
int main(){
Queue q;
ElemType c;
InitQueue(&q);
EnterQueue(&q,'a');
EnterQueue(&q,'f');
EnterQueue(&q,'g');
EnterQueue(&q,'e');
DeleteQueue(&q,&c);
printf("%c \n", c);
printf("&&&&%d", IsQueueEmpty(q));
DeleteQueue(&q,&c);
printf("%c \n", c);
return 0;
}
*/
//返回顶点v在G中的下标
int LocateVertax(GraphAL G, ElemType v){
int i;
for( i = 0; i < G.vertaxNum; i++ ){
if( G.VertaxArray[i].data == v )
return i;
}
return -1;
}
//通过下标得到元素的值
ElemType GetValueFromIndex(GraphAL G, int index){
return G.VertaxArray[index].data;
}
//创建邻接表无向图
Status CreateUDG_AdjacencyList(GraphAL* G){
int i;
ElemType v,w;
int index_v, index_w;
EageNodePtr vPtr,wPtr;
printf(" Create Undigraph\n");
printf("Please enter the number of Vertax and Eage: ");
scanf("%d %d%*c", &(G->vertaxNum), &(G->eageNum));
printf("ok, please input the value of %d Vertax\n", G->vertaxNum);
for( i = 0; i < G->vertaxNum; i++ ){
scanf("%c%*c", &(G->VertaxArray[i].data));
G->VertaxArray[i].firstEage = NULL;
}
for( i = 0; i < G->eageNum; i++ ){
printf("ok, please input the two Vertax of Eage %d (Sepearted by Space) :", i+1);
scanf("%c %c%*c", &v,&w); //一条边的两个顶点v w
index_v = LocateVertax(*G, v);
index_w = LocateVertax(*G, w);
wPtr = (EageNode*)malloc(sizeof(EageNode));
if( !wPtr )
return ERROR;
wPtr->adjacentVertax = index_w;
wPtr->nextAdjacentVertax = G->VertaxArray[index_v].firstEage;
G->VertaxArray[index_v].firstEage = wPtr;
vPtr = (EageNode*)malloc(sizeof(EageNode));
if( !vPtr )
return ERROR;
vPtr->adjacentVertax = index_v;
vPtr->nextAdjacentVertax = G->VertaxArray[index_w].firstEage;
G->VertaxArray[index_w].firstEage = vPtr;
}
return OK;
}
//在图G中找v的第一个邻接顶点,找到则返回该顶点在邻接表中的位置,若没有则返回-1
int FirstAdjacentVertax(GraphAL G, ElemType v){
int index_v;
index_v = LocateVertax(G, v);
if( G.VertaxArray[index_v].firstEage == NULL )
return -1;
else
return (G.VertaxArray[index_v].firstEage)->adjacentVertax;
}
//在图G中找v的从w开始的下一个相邻的顶点
int NextAdjacentVertax(GraphAL G, ElemType v, ElemType w ){
int index_v,index_w;
EageNodePtr p;
index_v = LocateVertax(G, v);
index_w = LocateVertax(G, w);
if( G.VertaxArray[index_v].firstEage == NULL )
return -1;
p = G.VertaxArray[index_v].firstEage; //p pointer to first node
while( p->nextAdjacentVertax != NULL ){
if( p->adjacentVertax == index_w )
return p->nextAdjacentVertax->adjacentVertax;
p = p->nextAdjacentVertax;
}
return -1;
}
//DFS深度优先遍历图:使用递归算法,算法思想:
// 1:从v顶点开始,visit(v),将其设置为已遍历
// 2: 获得v的第一个邻接顶点w,若其存在并且没有访问过,递归遍历;
// 3: 获得v的从w之后的邻接点,若其存在并且没有访问过,递归遍历;直到所有都访问过
int visitedArray[MAX_VERTAX_SIZE];
void visit(ElemType c){
printf("%c ", c);
}
Status DFS(GraphAL G, ElemType v){
ElemType w;
visit(v);
visitedArray[LocateVertax(G, v)] = 1;
for( w = GetValueFromIndex(G, FirstAdjacentVertax(G, v)); LocateVertax(G, w) != -1; w = GetValueFromIndex(G, NextAdjacentVertax(G, v, w))){
if( visitedArray[LocateVertax(G, w)] != 1 )
DFS(G, w);
}
return OK;
}
Status DFSTraverse(GraphAL G){
int i;
for( i = 0; i < G.vertaxNum; i++ )
visitedArray[i] = 0;
for( i = 0; i < G.vertaxNum; i++ )
if( visitedArray[i] != 1 )
DFS(G, GetValueFromIndex(G, i));
return OK;
}
//BFS(Breadth First Search)
Status BFS(GraphAL G){
int i,j;
Queue q;
ElemType c;
InitQueue(&q);
for(i = 0; i < G.vertaxNum; i++)
visitedArray[i] = 0;
for(i = 0; i < G.vertaxNum; i++){ //这个for实际执行的次数是连通分量的个数
if( visitedArray[i] == 0 ){
EnterQueue(&q, G.VertaxArray[i].data);
visitedArray[i] = 1;
while( IsQueueEmpty(q) != OK ){
DeleteQueue(&q, &c);
visit(c);
for( j = FirstAdjacentVertax(G, c); j != -1; j = NextAdjacentVertax(G, c, GetValueFromIndex(G, j))){
if( visitedArray[j] == 0 ){
EnterQueue(&q, GetValueFromIndex(G, j));
visitedArray[j] = 1;
}
}
}
}
}
}
//打印无向图的邻接表
void PrintUDG_AdjacentList(GraphAL G){
int i;
EageNodePtr p;
printf(" Adjacency List \n");
for( i = 0; i < G.vertaxNum; i++ ){
printf(" %d %c ",i, G.VertaxArray[i]);
p = G.VertaxArray[i].firstEage;
while( p != NULL ){
printf("-->%d", p->adjacentVertax);
p = p->nextAdjacentVertax;
}
printf("\n");
}
}
int main(){
GraphAL G;
CreateUDG_AdjacencyList(&G);
PrintUDG_AdjacentList(G);
printf(" DFS(Depth First Search) of UDG(Undigraph)\n");
DFSTraverse(G);
printf("\n BFS(Breadth First Search) of UDG(Undigraph)\n");
BFS(G);
return 0;
}
图的邻接表存储表示 图的深度优先遍历和图的广度优先遍历
最新推荐文章于 2024-06-25 21:00:00 发布