邻接表的结构定义:
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" ) ;
}