用C语言创建邻接表,并实现DFS+BFS

邻接表的结构定义:

typedef struct EdgeNode //边表节点
{
    int index ;
    struct EdgeNode *next ;
}EdgeNode ;

typedef struct VertexNode //表头结点表结点
{
    char data ;
    EdgeNode *firstedge ;
}AdjList[ MAXVerTex ] ;

typedef struct
{
    AdjList adjlist ;
    int vexnum , edgenum ;
}GraphAdjList ;

查找结点元素在边表节点表中的下标:

int Locate( GraphAdjList G , char ch )
{
    int i ;
    for( i = 0 ; i < G.vexnum ; i++ )
        if( G.adjlist[ i ].data == ch )
            break ;
    return i ;
}

用邻接表创建无向图:

1. 用头插法创建边表
2. 由于是无向图,创建vi----vj这条边后,也要创建vj----vi这条边
3. 用scanf()接受从键盘输入的节点元素时,要用getchar()来接收留在缓冲区的回车字符。当从键盘输入的是字符时,这点尤其要注意。

void CreateALGraph( GraphAdjList *G )
{
    int k , i , j ;
    EdgeNode *e ;
    char vi , vj  ;
    printf( "请输入结点的个数:" ) ;
    scanf( "%d" , &G->vexnum ) ;
    getchar() ;

    for( k = 0 ; k < G->vexnum ; k++ )
    {
        printf( "请输入第%d个结点的信息:" , k+1 ) ;
        scanf( "%c" , &G->adjlist[ k ].data ) ;
        getchar() ;

        G->adjlist[ k ].firstedge = NULL ;
    }

    printf( "请输入图中边的条数:" ) ;
    scanf( "%d" , &G->edgenum ) ;
    getchar() ;

    for( k = 0 ; k < G->edgenum ; k++ )
    {
        printf( "请输入每条边所对应的两个结点信息:" ) ;
        scanf( "%c %c" , &vi , &vj ) ;
        getchar() ;

        i = Locate( *G , vi ) ;
        j = Locate( *G , vj ) ;

        e = ( EdgeNode * )malloc( sizeof( EdgeNode ) ) ;
        e->index = j ;
        e->next = G->adjlist[ i ].firstedge ;
        G->adjlist[ i ].firstedge = e ;

        e = ( EdgeNode * )malloc( sizeof( EdgeNode ) ) ; 
        e->index = i ;
        e->next = G->adjlist[ j ].firstedge ;
        G->adjlist[ j ].firstedge = e ;
    }
}

DFS:

相当于数的前序遍历

void DFS( GraphAdjList G , int i )
{
    EdgeNode *p ;
    visited[ i ] = TRUE ;
    printf( "%c " , G.adjlist[ i ].data ) ;
    p = G.adjlist[ i ].firstedge ;

    while( p )
    {
        if( !visited[ p->index ] )
            DFS( G , p->index ) ;
        p = p->next ;
    }
}

void DFSTraverse( GraphAdjList G )
{
    int i ;
    for( i = 0 ; i <G.vexnum ; i++ )
        visited[ i ] = FALSE ;

    for( i = 0 ; i < G.vexnum ; i++ )
        if( !visited[ i ] )
            DFS( G , i ) ;
    printf( "\n" ) ;
}

BFS:

相当于树的层序遍历
要借助队列来实现,这里用的是循环队列,判断队列是否为空,出队和入队操作较简单,就不一一写出,这些都放在源代码里,由于删除队列并不需要返回删除的元素,因此删除队列的函数中只有队列这一个参数。

void BFSTraverse( GraphAdjList G )
{
    int i ;
    char temp ;
    EdgeNode *p ;
    Queue Q ;
    InitQueue( &Q ) ;
    for( i = 0 ; i < G.vexnum ; i++ )
        visited[ i ] = FALSE ;

    for( i = 0 ; i < G.vexnum ; i++ )
    {
        if( !visited[ i ] )
        {
            visited[ i ] = TRUE ;
            printf( "%c " , G.adjlist[ i ].data ) ;
            EnQueue( &Q , G.adjlist[ i ].data ) ;

            while( !EmptyQueue( Q ) )
            {
                DeQueue( &Q ) ;
                p = G.adjlist[ i ].firstedge ;

                while( p )
                {
                    if( !visited[ p->index ] )
                    {
                        visited[ p->index ] = TRUE ;
                        printf( "%c " , G.adjlist[ p->index ].data ) ;
                        EnQueue( &Q , G.adjlist[ p->index ].data ) ;
                    }
                    p = p->next ;
                }
            }
        }
    }
    printf( "\n" ) ;
}

附上源代码:

#include<stdio.h>
#include<stdlib.h>
#define MAXVEX 100
#define TRUE 1
#define FALSE 0

typedef int Boolean ;

typedef struct EdgeNode
{
    int index ;
    struct EdgeNode *next ;
}EdgeNode ;

typedef struct VertexNode
{
    EdgeNode *firstedge ;
    char data ;
}EdgeAdjlist[ MAXVEX ] ;

typedef struct
{
    EdgeAdjlist adjlist ;
    int NumVerex , NumEdge ;
}GraphAdjList ;

typedef struct
{
    char *base ;
    int front ;
    int rear ;
}Queue ;

void CreateGraph( GraphAdjList *G ) ;
int Locate( GraphAdjList G , char ch ) ;
void DFS( GraphAdjList G , int i ) ;
void DFSTraverse( GraphAdjList G ) ;

void InitQueue( Queue *Q ) ;
void EnQueue( Queue *Q , char ch ) ;
void DeQueue( Queue *Q ) ;
int EmptyQueue( Queue Q ) ;
void BFSTraverse( GraphAdjList G ) ;

Boolean visited[ MAXVEX ] ;

int main( void )
{
    GraphAdjList G ;
    CreateGraph( &G ) ;
    printf( "DFS: " ) ;
    DFSTraverse( G ) ;
    printf( "BFS: " ) ;
    BFSTraverse( G ) ;

    return 0 ;
}

int Locate( GraphAdjList G , char ch )
{
    int i ;
    for( i = 0 ; i < G.NumVerex ; i++ )
        if( ch == G.adjlist[ i ].data )
            break ;
    return i ;
}

void CreateGraph( GraphAdjList *G )
{
    int i , pos1 , pos2 ;
    char x , y ;
    EdgeNode *e ;
    printf( "请输入结点的个数:" ) ;
    scanf( "%d" , &G->NumVerex ) ;
    getchar() ;

     for( i = 0 ; i < G->NumVerex ; i++ )
     {
         G->adjlist[ i ].firstedge = NULL ;
         printf( "请输入第%d个结点的信息:" , i+ 1 ) ;
         scanf( "%c" , &G->adjlist[ i ].data ) ;
         getchar() ;
     }

     printf( "请输入边的条数:" ) ;
     scanf( "%d" , &G->NumEdge ) ;
     getchar() ;

     for( i = 0 ; i < G->NumEdge ; i++ )
     {
         printf( "请输入第%d条边的两个结点的信息:" ,  i + 1 ) ;
         scanf( "%c %c" , &x , &y ) ;
         getchar() ;

         pos1 = Locate( *G , x ) ;
         pos2 = Locate( *G , y ) ;

         e = ( EdgeNode * )malloc( sizeof( EdgeNode ) ) ;
         e->index = pos2 ;
         e->next = G->adjlist[ pos1 ].firstedge ;
         G->adjlist[ pos1 ].firstedge = e ;

         e = ( EdgeNode * )malloc( sizeof( EdgeNode ) ) ;
         e->index = pos1 ;
         e->next = G->adjlist[ pos2 ].firstedge ;
         G->adjlist[ pos2 ].firstedge = e ;
     }
}

void DFS( GraphAdjList G , int i )
{
    EdgeNode *p ;
    printf( "%c " , G.adjlist[ i ].data ) ;
    visited[ i ] = TRUE ;

    p = G.adjlist[ i ].firstedge ;
    while( p )
    {
        if( !visited[ p->index ] )
            DFS( G , p->index ) ;
        p = p->next ;
    }
}

void DFSTraverse( GraphAdjList G )
{
    int i ;
    for( i = 0 ; i < MAXVEX ; i++ )
        visited[ i ] = FALSE ;

    for( i = 0 ; i < G.NumVerex ; i++ )
        if( !visited[ i ] )
            DFS( G , i ) ;
    printf( "\n" ) ;
}
void InitQueue( Queue *Q )
{
    Q->base = ( char * )malloc( sizeof( char ) * MAXVEX ) ;
    Q->front = Q->rear = 0 ;
}

void EnQueue( Queue *Q , char ch )
{
    if( ( Q->rear + 1 ) % MAXVEX == Q->front )
        exit( -1 ) ;
    else
    {
        Q->base[ Q->rear ] = ch ;
        Q->rear = ( Q->rear + 1 ) % MAXVEX ;
    }
}

int EmptyQueue( Queue Q )
{
    if( Q.front == Q.rear )
        return 1 ;
    else
        return 0 ;
}

void DeQueue( Queue *Q )
{
    if( EmptyQueue( *Q ) )
        exit( -1 ) ;
    else
        Q->front = ( Q->front + 1 ) % MAXVEX ;
}

void BFSTraverse( GraphAdjList G )
{
    int i ;
    EdgeNode *p ;
    for( i = 0 ; i < MAXVEX ; i++ )
        visited[ i ] = FALSE ;

    Queue Q ;
    InitQueue( &Q ) ;
    for( i= 0 ; i < G.NumVerex ; i++ )
    {
        if( !visited[ i ] )
        {
            printf( "%c " , G.adjlist[ i ].data ) ;
            EnQueue( &Q , G.adjlist[ i ].data ) ;
            visited[ i ] = TRUE ;

            while( !EmptyQueue( Q ) )
            {
                DeQueue( &Q ) ;
                p = G.adjlist[ i ].firstedge ;
                while( p )
                {
                    if( !visited[ p->index ] )
                    {
                        EnQueue( &Q , G.adjlist[ p->index ].data ) ;
                        printf( "%c " , G.adjlist[ p->index ].data ) ;
                        visited[ p->index ] = TRUE ;
                    }

                    p = p->next ;
                }
            }
        }
    }
    printf( "\n" ) ;
}

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值