邻接表的部分操作和BFS遍历

有向图可以指向本身,则边表的长度可以和顶点表长度相同

    for(i=0;i<G.VerNum;i++)
    {
        ArcNode *p=G.Ver[i].first;
        for(j=0;j<G.VerNum;j++)        //有向图顶点可以指向自己 
                .
                .
                .
        }

创造图时,对于边表采用头插法

ArcNode *arcnode=(ArcNode*)malloc(sizeof(ArcNode));
arcnode->adjvex=x;
arcnode->next=G.Ver[i].first;
G.Ver[i].first=arcnode;

对于图的基本函数:FirstNeighbor(G,x)和NextNeighbor(G,x,y)

FirstNeighbor(G,x):返回与x顶点相邻的第一个顶点索引号,对表格来说,返回1

NextNeighbor(G,x,y):返回与x顶点相邻,除了y顶点外的下一个顶点的索引号,对表格来说,返回2

0 1 2
x y z

 

 

int ArrNum(Graph G,int ver)
{
    for(int i=0;i<G.VerNum;i++)
        if(G.Ver[i].data==ver)
                return i;
    return -1;
}

int FirstNeighbor(Graph G,int ver)
{
    int x=ArrNum(G,ver);
    if(x!=-1 && G.Ver[x].first!=NULL)
        return ArrNum(G,G.Ver[x].first->adjvex);
    return -1;
}

int NextNeighbor(Graph G,int ver,int w)
{
    int x=ArrNum(G,ver);
    ArcNode *arcnode=G.Ver[x].first;
    while(arcnode!=NULL && arcnode->adjvex!=w)
        arcnode=arcnode->next;
    if(arcnode->next!=NULL)
        return ArrNum(G,arcnode->next->adjvex);
    return -1;
}

广度优先遍历:

1、BFSTraverse(Graph G)

  对于图这种数据结构,可能会存在好几个连通分量,对G2而言,一次广度优先无法将图中所有顶点都遍历一遍

  

void BFSTraverse(Graph G)
{
    for(int i=0;i<G.VerNum;i++)
        visited[i]=false;
    for(int i=0;i<G.VerNum;i++)
        if(!visited[i])
            BFS(G,i);
}

2、BFS(Graph G,int v)

入队的是对应顶点的第一个边表结点,手动模拟一边就清楚了。

bool visited[MaxSize];
void BFS(Graph G,int v)
{
    printf("%d ", G.Ver[v].data);
    visited[v] = true;
    Queue Q;
    InitQueue(Q);
    EnQueue(Q, G.Ver[v].first);
    while (!isEmpty(Q))
    {
        ArcNode* arcnode;
        DeQueue(Q, arcnode);
        while (arcnode != NULL)
        {
            int i = ArrNum(G,arcnode->adjvex);
            if (!visited[i])
            {
                printf("%d ", G.Ver[i].data);
                visited[i] = true;
                EnQueue(Q, G.Ver[i].first);
            }
            arcnode = arcnode->next;
        }
    }
}

完整代码:

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

#define MaxSize 20

typedef struct ArcNode{            //边表结点 
    struct ArcNode *next;
    int adjvex;
}ArcNode;

typedef struct VNode{            //主表结点 
    int data;
    ArcNode *first;
}VNode,AdjList[MaxSize];

typedef struct{                    //
    AdjList Ver;
    int VerNum,EdgeNum;
}Graph;

typedef struct{
    ArcNode *data[MaxSize];
    int front,rear;
}Queue;

void InitQueue(Queue &Q)
{
    Q.front=Q.rear=0;
}

bool isEmpty(Queue Q)
{
    if(Q.rear==Q.front)
        return true;
    return false;
}

bool isFull(Queue Q)
{
    if((Q.rear+1)%MaxSize==Q.front)
        return true;
    return false;
}

bool EnQueue(Queue &Q,ArcNode *arcnode)
{
    if(isFull(Q))
        return false; 
    Q.data[Q.rear]=arcnode;
    Q.rear=(Q.rear+1)%MaxSize;
    return true;
}

bool DeQueue(Queue &Q,ArcNode* &arcnode)
{
    if(isEmpty(Q))
        return false;
    arcnode=Q.data[Q.front];
    Q.front=(Q.front+1)%MaxSize;
    return true;
}

void CreateGraph(Graph &G)
{
    int x,i,j;
    printf("请输入顶点元素:\n");
    for(i=0;i<MaxSize;i++)
    {
        scanf("%d",&x);
        if(x==-1)
            break;
        G.Ver[i].data=x;
        G.Ver[i].first=NULL;
        G.VerNum++;
    }
    
    printf("请输入边表:\n"); 
    for(i=0;i<G.VerNum;i++)
    {
        ArcNode *p=G.Ver[i].first;
        for(j=0;j<G.VerNum;j++)        //有向图顶点可以指向自己 
        {
            scanf("%d",&x);
            if(x==-1)
                break;
            ArcNode *arcnode=(ArcNode*)malloc(sizeof(ArcNode));
            arcnode->adjvex=x;
            arcnode->next=G.Ver[i].first;
            G.Ver[i].first=arcnode;
            G.EdgeNum++; 
        }
    }
}

void DisplayGraph(Graph G)
{
    int i,j;
    printf("顶点元素为:\n");
    for(i=0;i<G.VerNum;i++)
        G.Ver[i].data;
    
    printf("边为:\n");
    for(i=0;i<G.VerNum;i++)
    {
        printf("%d->",G.Ver[i].data);
        ArcNode *arc=G.Ver[i].first;
        while(arc!=NULL)
        {
            printf("%d  ",arc->adjvex);
            arc=arc->next;
        }
        printf("\n");
    }
    
    printf("顶点元素共有%d个\n",G.VerNum);
    printf("边有%d条\n",G.EdgeNum); 
}

int ArrNum(Graph G,int ver)
{
    for(int i=0;i<G.VerNum;i++)
        if(G.Ver[i].data==ver)
                return i;
    return -1;
}

int FirstNeighbor(Graph G,int ver)
{
    int x=ArrNum(G,ver);
    if(x!=-1 && G.Ver[x].first!=NULL)
        return ArrNum(G,G.Ver[x].first->adjvex);
    return -1;
}

int NextNeighbor(Graph G,int ver,int w)
{
    int x=ArrNum(G,ver);
    ArcNode *arcnode=G.Ver[x].first;
    while(arcnode!=NULL && arcnode->adjvex!=w)
        arcnode=arcnode->next;
    if(arcnode->next!=NULL)
        return ArrNum(G,arcnode->next->adjvex);
    return -1;
}

bool visited[MaxSize];
void BFS(Graph G,int v)
{
    printf("%d ", G.Ver[v].data);
    visited[v] = true;
    Queue Q;
    InitQueue(Q);
    EnQueue(Q, G.Ver[v].first);
    while (!isEmpty(Q))
    {
        ArcNode* arcnode;
        DeQueue(Q, arcnode);
        while (arcnode != NULL)
        {
            int i = ArrNum(G,arcnode->adjvex);
            if (!visited[i])
            {
                printf("%d ", G.Ver[i].data);
                visited[i] = true;
                EnQueue(Q, G.Ver[i].first);
            }
            arcnode = arcnode->next;
        }
    }
}

void BFSTraverse(Graph G)
{
    for(int i=0;i<G.VerNum;i++)
        visited[i]=false;
    for(int i=0;i<G.VerNum;i++)
        if(!visited[i])
            BFS(G,i);
}

int main()
{
    Graph G;
    CreateGraph(G);
    DisplayGraph(G);
    BFSTraverse(G);
    
    return 0;    
} 

 

posted on 2023-09-03 21:51  四马路弗洛伊德  阅读(198)  评论(0)    收藏  举报

导航