ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

数据结构无向图的建立和遍历(邻接链表)

2021-12-14 09:35:13  阅读:145  来源: 互联网

标签:node vexs 遍历 int 链表 无向 firstNode 顶点 ENode


数据结构无向图的邻接链表的存储方式:顶点用一维数组储存,每个顶点构成一个线性表,用单链表的形式表达

1.结构体的创建

 

#define MAX 20

//线性表中的结点 
typedef struct ENode{
    int index;  //该数据的下标 
    struct ENode *next;//下一个结构体 
}ENode;

//顶点信息
typedef struct Node{
    char data;
    struct ENode *firstNode;  //指向节点的指针 
}Node; 

//链接表的信息
typedef struct Graph{
    int vexNum;  //顶点数量
    int arcNum;  //边的数量
    Node vexs[MAX];   //顶点数组  用.的方式访问 
}Graph,*myGraph;

2.无向图的邻接链表的创建

void createGraph(myGraph &G)
{
    G=(Graph*)malloc(sizeof(Graph));  //结构体的指针要初始化
     
    int i,j,k;
    char v1,v2;    //边的两个顶点 
    printf("请输入顶点的数量:");
    scanf("%d",&G->vexNum);
    printf("请输入边的数量:");
    scanf("%d",&G->arcNum);
    
    printf("请依次将顶点数据输入进来\n");
    for(i=0;i<G->vexNum;i++)
    {  
        getchar();
        scanf("%c",&G->vexs[i].data);
        G-> vexs[i].firstNode=NULL;//顶点指向的线性表为空 
    }
    
    printf("请依次将边输入进来\n");
    for(int i=0;i<G->arcNum;i++)
    {
        getchar();
        scanf("%c%c",&v1,&v2);
        j=getLocate(G,v1);  //获取下标
        k=getLocate(G,v2);  //获取下标
        
        //v1v2边   jk
        ENode *currentNode1=(ENode*)malloc(sizeof(Node));//生成临时结点
        currentNode1->index=k; //储存的下标
        currentNode1->next=NULL; //指针指向的节点为空 
        
        if(G->vexs[j].firstNode==NULL)//当该顶点没有邻接点时 
        {
            G->vexs[j].firstNode=currentNode1; //指向这个结点
        } 
        else  //该顶点有邻接点时 
        {
            ENode *p=G->vexs[j].firstNode;  //避免 G->vexs[j].firstNode 会发生改变 
            while(p->next!=NULL)  //指向该顶点线性表中的最后一个节点 
            {
                p=p->next;
            }
            p->next=currentNode1; //指向这个结点 
        }
        
        //v2v1边   kj
        ENode *currentNode2=(ENode*)malloc(sizeof(Node));//生成临时结点
        currentNode2->index=j; //储存的下标
        currentNode2->next=NULL; //指针指向的节点为空 
            
        if(G->vexs[k].firstNode==NULL)//当该顶点没有邻接点时 
        {
            G->vexs[k].firstNode=currentNode2; //指向这个结点 
        } 
        else  //该顶点有邻接点时 
        {
            ENode *q=G->vexs[k].firstNode;   //避免 G->vexs[j].firstNode 会发生改变 
            while(q->next!=NULL)  //指向该顶点线性表中的最后一个节点 
            {
                q=q->next;
            }
            q->next=currentNode2; //指向这个结点 
        }
    }  
}

3.邻接链表的深度优先遍历

void DFS(myGraph G,int i,int *visit)
{
    if(!visit[i])//如果没有访问过 
    {
        ENode *node;//临时结点 
        visit[i]=1;
        printf("%c ",G->vexs[i].data); //输出该顶点信息
        node=G->vexs[i].firstNode;   //避免破坏  G->vexs[i].firstNode
        
        while(node!=NULL)//该邻接点不为空
        {
            if(!visit[node->index]) //如果该邻接点没有被访问过 
            {
                DFS(G,node->index,visit);
            }
            node=node->next;
        } 
    }
}

4.邻接链表的广度优先遍历

void BFS(myGraph G,int *visit)  //队列满足先进先出的规律 
{
    int front=0;
    int rear=0;
    int Queue[G->vexNum]; 
    int i,j;
    ENode *node;
    
    for(i=0;i<G->vexNum;i++)//避免出现没有邻接点的顶点 
    {
        if(!visit[i]) //如果没有访问过 
        {
            visit[i]=1; //该顶点被访问过
            printf("%c ",G->vexs[i].data);
            Queue[rear++]=i;   //入队列 
        }
        
        while(front!=rear)
        {
            j=Queue[front++];  //出队列 
            node=G->vexs[j].firstNode;
            while(node!=NULL)
            {
                if(!visit[node->index])
                {
                    visit[node->index]=1;
                    printf("%c ",G->vexs[node->index].data);
                    Queue[rear++]=node->index;   //入队列 
                }
                node=node->next;
            }
        }
    }
}

所有的代码如下:

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

#define MAX 20

//线性表中的结点 
typedef struct ENode{
    int index;  //该数据的下标 
    struct ENode *next;//下一个结构体 
}ENode;

//顶点信息
typedef struct Node{
    char data;
    struct ENode *firstNode;  //指向节点的指针 
}Node; 

//链接表的信息
typedef struct Graph{
    int vexNum;  //顶点数量
    int arcNum;  //边的数量
    Node vexs[MAX];   //顶点数组  用.的方式访问 
}Graph,*myGraph;

//获取顶点的下标
int getLocate(myGraph G,char v)
{
    int i;
    for(i=0;i<G->vexNum;i++)
    {
        if(v==G->vexs[i].data)
        {
            return i;
        }
    }
    return -1;
}

//创建链表
void createGraph(myGraph &G)
{
    G=(Graph*)malloc(sizeof(Graph));  //结构体的指针要初始化
     
    int i,j,k;
    char v1,v2;    //边的两个顶点 
    printf("请输入顶点的数量:");
    scanf("%d",&G->vexNum);
    printf("请输入边的数量:");
    scanf("%d",&G->arcNum);
    
    printf("请依次将顶点数据输入进来\n");
    for(i=0;i<G->vexNum;i++)
    {  
        getchar();
        scanf("%c",&G->vexs[i].data);
        G-> vexs[i].firstNode=NULL;//顶点指向的线性表为空 
    }
    
    printf("请依次将边输入进来\n");
    for(int i=0;i<G->arcNum;i++)
    {
        getchar();
        scanf("%c%c",&v1,&v2);
        j=getLocate(G,v1);  //获取下标
        k=getLocate(G,v2);  //获取下标
        
        //v1v2边   jk
        ENode *currentNode1=(ENode*)malloc(sizeof(Node));//生成临时结点
        currentNode1->index=k; //储存的下标
        currentNode1->next=NULL; //指针指向的节点为空 
        
        if(G->vexs[j].firstNode==NULL)//当该顶点没有邻接点时 
        {
            G->vexs[j].firstNode=currentNode1; //指向这个结点
        } 
        else  //该顶点有邻接点时 
        {
            ENode *p=G->vexs[j].firstNode;  //避免 G->vexs[j].firstNode 会发生改变 
            while(p->next!=NULL)  //指向该顶点线性表中的最后一个节点 
            {
                p=p->next;
            }
            p->next=currentNode1; //指向这个结点 
        }
        
        //v2v1边   kj
        ENode *currentNode2=(ENode*)malloc(sizeof(Node));//生成临时结点
        currentNode2->index=j; //储存的下标
        currentNode2->next=NULL; //指针指向的节点为空 
            
        if(G->vexs[k].firstNode==NULL)//当该顶点没有邻接点时 
        {
            G->vexs[k].firstNode=currentNode2; //指向这个结点 
        } 
        else  //该顶点有邻接点时 
        {
            ENode *q=G->vexs[k].firstNode;   //避免 G->vexs[j].firstNode 会发生改变 
            while(q->next!=NULL)  //指向该顶点线性表中的最后一个节点 
            {
                q=q->next;
            }
            q->next=currentNode2; //指向这个结点 
        }
    }  
}


//邻接链表的深度优先遍历
void DFS(myGraph G,int i,int *visit)
{
    if(!visit[i])//如果没有访问过 
    {
        ENode *node;//临时结点 
        visit[i]=1;
        printf("%c ",G->vexs[i].data); //输出该顶点信息
        node=G->vexs[i].firstNode;   //避免破坏  G->vexs[i].firstNode
        
        while(node!=NULL)//该邻接点不为空
        {
            if(!visit[node->index]) //如果该邻接点没有被访问过 
            {
                DFS(G,node->index,visit);
            }
            node=node->next;
        } 
    }
}

//邻接链表的广度优先遍历
void BFS(myGraph G,int *visit)  //队列满足先进先出的规律 
{
    int front=0;
    int rear=0;
    int Queue[G->vexNum]; 
    int i,j;
    ENode *node;
    
    for(i=0;i<G->vexNum;i++)//避免出现没有邻接点的顶点 
    {
        if(!visit[i]) //如果没有访问过 
        {
            visit[i]=1; //该顶点被访问过
            printf("%c ",G->vexs[i].data);
            Queue[rear++]=i;   //入队列 
        }
        
        while(front!=rear)
        {
            j=Queue[front++];  //出队列 
            node=G->vexs[j].firstNode;
            while(node!=NULL)
            {
                if(!visit[node->index])
                {
                    visit[node->index]=1;
                    printf("%c ",G->vexs[node->index].data);
                    Queue[rear++]=node->index;   //入队列 
                }
                node=node->next;
            }
        }
    }
} 

//打印该邻接表
void printfGraph(Graph G)  //打印表不要用指针,这样可能会改变图的结构 
{
    for(int i=0;i<G.vexNum;i++)
    {
        printf("%c ",G.vexs[i].data);
        while(G.vexs[i].firstNode!=NULL)
        {
            printf("%d ",G.vexs[i].firstNode->index);
            G.vexs[i].firstNode=G.vexs[i].firstNode->next;
        }
        printf("\n");
    } 
}

int main()
{
    Graph *G;  //申明邻接链表的对象
    createGraph(G);  //创建邻接链表
    printfGraph(*G);   //打印该邻接链表 
    
    int visit[G->vexNum]={0};
    printf("图的邻接链表的深度优先遍历如下:\n");
    for(int i=0;i<G->vexNum;i++)  //避免出现没有邻接点的顶点 
    {
        DFS(G,i,visit);
    }
    printf("\n");
    
    for(int i=0;i<G->vexNum;i++)
    {
        visit[i]=0;
    }
    printf("图的邻接链表的广度优先遍历如下:\n");
    BFS(G,visit); 
    return 0;
}

 

标签:node,vexs,遍历,int,链表,无向,firstNode,顶点,ENode
来源: https://www.cnblogs.com/nanamiyi/p/15686256.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有