zoukankan      html  css  js  c++  java
  • 图的邻接表存储c实现(DFS遍历)

    先简要列出实现过程中所需要的数据结构。

    如下图

    对于这个图而言,它的邻接表可以这样表示,当然表现形式可以多样,这只是我随便画的一种表示方法。

                       顶点表                                          边表

    我们把第一个表即上面标着fixedvex的这个表称作顶点表,后边的称为边表。

     上图所示,边表的结构应该这样写:

    //定义一个边表节点的结构 
    typedef struct node{
    	int adjvex;
    	//int Mark; //用于标记是否被访问过 
    	node *next;
    }VerAndedge; 
    

     包含一个adjvex,保存某个结点;

     一个next指向下个边表结构,构成各个顶点间的联系。

     既然有了边表的结构,那么顶点表的结构应该如下:

    //顶点表 
    typedef struct Fixed{
        int Mark;
        int fixedvex;
        node* firsthead;
    }Fixednode;

    包含一个fixedvex保存顶点;

    由图中可知,顶点表指向边表,所以理所当然包含一个指向边表的指针:一个 firsthead ;

     有了以上这2个结构,我们便可以着手开始实现它了。

     首先明确要有几个结点,也就是要有几个 fixedvex ,由于每个fixedvex都有其特定的关系,所以我们应该生成结构数组来保存这些内容,所以我们再建立如下的结构保存,为什么创建这个结构?下面将清晰。 

    //保存各个顶点信息。 
    typedef struct ALgarph{
        int a,b;
        Fixednode adjlist[100];
    }ALgarph;

    既然要创建一个邻接表,那就写一个函数吧

     void creat(ALgarph *);  

     首先必须对这个函数传入内容,那我们便创建一个结构,并传入

     ALgarph *S = (ALgarph*)malloc(sizeof(ALgarph));

     creat(S);

     这个creat到底怎么写呢,下面直接给出代码,读者通过注释自己理解。

    void creat(ALgarph *S)
    {
        int i,x,y;
        printf("请输入顶点的个数和边的数量:");
        scanf("%d%d",&S->a,&S->b);   //获取到顶点和边的信息
             
        for(i=0;i<S->a;i++)
        {
            printf("输入顶点,建立顶点表:");   //建立顶点表。 
            scanf("%d",&S->adjlist[i].fixedvex);
            S->adjlist[i].firsthead= NULL;  //初始化firsthead 
            S->adjlist[i].Mark = 0;//初始化标记 
    
        }
        printf("建立边表
    ");//建立边表,在建立的同时将他们的关系对应
        for(i=0;i<S->b;i++)
        {
            printf("读入(vi-vj):");
            scanf("%d%d",&x,&y);
            VerAndedge * G = (VerAndedge *)malloc(sizeof(VerAndedge)); //生成一个边表结构 
        //    G->Mark = 0; //标记为零表示未访问 
            G->adjvex= y;
            G->next= S->adjlist[x].firsthead; //插入到头部
            S->adjlist[x].firsthead= G;
            //因为是无向图,所以调换个节点的关系,再次生成。 
            G= (VerAndedge *)malloc(sizeof(VerAndedge));
        //    G->Mark = 0;
            G->adjvex= x;
            G->next= S->adjlist[y].firsthead; //插入到头部
            S->adjlist[y].firsthead= G;
        
        }
    }

    创建完毕后就是输出这个邻接表了。

        VerAndedge *current;
        for(i=0;i<S->a;i++)
        {
            printf("%d->",S->adjlist[i].fixedvex);
            current = S->adjlist[i].firsthead;
            while(current!=NULL)
            {
                printf("%d->",current->adjvex);
                current= current->next;
            }
            printf("
    ");
        }

    好了,那么完整的程序如下:

    /*2014/12/1*/
    /*邻接表表示的图的深度优先遍历*/
    
    /*这个代码是在昨天的基础上改写了,
    添加了DFS遍历的2个函数,
    注释着实觉得没有添加的必要.
    反正是采用了递归的方法 
    */
    
    
    
    #include <stdio.h>
    #include <stdlib.h>
    
    //定义一个边表节点的结构 
    typedef struct node{
        int adjvex;
        //int Mark; //用于标记是否被访问过 
        node *next;
    }VerAndedge; 
    
    //顶点表 
    typedef struct Fixed{
        int Mark;
        int fixedvex;
        node* firsthead;
    }Fixednode;
    
    //保存各个顶点信息。 
    typedef struct ALgarph{
        int a,b;
        Fixednode adjlist[100];
    }ALgarph;
    
    
    void creat(ALgarph *);
    void Adj_dfs(ALgarph *);
    void Adj_visit(ALgarph * ,int); 
    
    
    
    int main(void)
    {
        int i;
        ALgarph * S = (ALgarph *)malloc(sizeof(ALgarph));
        creat(S);
        
        VerAndedge *current;
        for(i=0;i<S->a;i++)
        {
            printf("%d->",S->adjlist[i].fixedvex);
            current = S->adjlist[i].firsthead;
            while(current!=NULL)
            {
                printf("%d->",current->adjvex);
                current= current->next;
            }
            printf("
    ");
        }
        
        
        Adj_dfs(S);
    
        return 0;
    }
    
     
    
    void creat(ALgarph *S)
    {
        int i,x,y;
        printf("请输入顶点的个数和边的数量:");
        scanf("%d%d",&S->a,&S->b);   //获取到顶点和边的信息
             
        for(i=0;i<S->a;i++)
        {
            printf("输入顶点,建立顶点表:");   //建立顶点表。 
            scanf("%d",&S->adjlist[i].fixedvex);
            S->adjlist[i].firsthead= NULL;  //初始化firsthead 
            S->adjlist[i].Mark = 0;//初始化标记 
    
        }
        printf("建立边表
    ");//建立边表,在建立的同时将他们的关系对应
        for(i=0;i<S->b;i++)
        {
            printf("读入(vi-vj):");
            scanf("%d%d",&x,&y);
            VerAndedge * G = (VerAndedge *)malloc(sizeof(VerAndedge)); //生成一个边表结构 
        //    G->Mark = 0; //标记为零表示未访问 
            G->adjvex= y;
            G->next= S->adjlist[x].firsthead; //插入到头部
            S->adjlist[x].firsthead= G;
            //因为是无向图,所以调换个节点的关系,再次生成。 
            G= (VerAndedge *)malloc(sizeof(VerAndedge));
        //    G->Mark = 0;
            G->adjvex= x;
            G->next= S->adjlist[y].firsthead; //插入到头部
            S->adjlist[y].firsthead= G;
        
        }
    }
    
    void Adj_dfs(ALgarph *S)
    {
        int vi;
        
        printf("请输入源点:
    ");
        scanf("%d",&vi);
        printf("遍历结果如下:");
        Adj_visit(S,vi);
    }
    
    void Adj_visit(ALgarph * S,int vi)
    {
        if(S->adjlist[vi].Mark == 0)
        {
            printf("%-2d",S->adjlist[vi].fixedvex);
            S->adjlist[vi].Mark = 1;
        }
    
        
        VerAndedge * current = S->adjlist[vi].firsthead;
        
        for(;current!=NULL;current=current->next)
        {
            if(S->adjlist[current->adjvex].Mark==0)
            Adj_visit(S,current->adjvex);
            
        }
        
        
        
    }

    运行结果如下

  • 相关阅读:
    子串匹配
    数据特征分析:3.统计分析 & 帕累托分析
    数据特征分析:2.对比分析
    数据特征分析:1.基础分析概述& 分布分析
    空间分析工具:GIS
    数据源
    07. Matplotlib 3 |表格样式| 显示控制
    06. Matplotlib 2 |折线图| 柱状图| 堆叠图| 面积图| 填图| 饼图| 直方图| 散点图| 极坐标| 图箱型图
    04. Pandas 3| 数值计算与统计、合并连接去重分组透视表文件读取
    05. Matplotlib 1 |图表基本元素| 样式参数| 刻度 注释| 子图
  • 原文地址:https://www.cnblogs.com/You0/p/4477538.html
Copyright © 2011-2022 走看看