图的深度优先遍历-C语言实现

来源:互联网 发布:周星驰 电视剧 知乎 编辑:程序博客网 时间:2024/05/02 04:19

我在大二上学期期末时候写的,大概2014年1月4号左右。我写在博客里一是为我以后复习所用,二是希望对需要的人有所帮助。

问题描述:

设计一个程序,输入一个无向图的顶点(编号 1,2,3···n)和边,使用邻接表存储结构存储该图,设定起始顶点后,按深度优先遍历算法遍历该图。输出顶点的访问次序。


#include<stdio.h>

#include<stdlib.h>
#include<malloc.h>
#include<string.h>
#define MAXLIN 40
/*----邻接表存储结构---*/
//-----------------表节点存储结构----------
typedef struct ArcNode{                                            //结构体
    int adjvex;     //表节点编号信息
    struct ArcNode *next;   
}ArcNode;
//-----------------头结点存储结构-----------
typedef struct VNode{            
    char vertex[5];      //节点信息
    ArcNode *link;
    int id;         //编号
}VNode;
//边节点
typedef struct Bian{                            //为了方便 加的一个结构体
    char one[5];                //存储边的第一个节点
    char two[5];                //存储边的第二个节点
}Bian;
typedef struct{
    VNode adjList[MAXLIN];     //顺序存储 头结点  头结点的数组
    int vexnum;       //顶点数
    int arcnum;            //边数
    Bian bian[MAXLIN];        //边的数组
    int kind;                //图的存储种类
}ALGraph;
int visit[MAXLIN];
//返回是第几个顶点
int PanDuan(char n[5],ALGraph &G)
{
    for(int i=0;i<G.vexnum;i++)
    {
        if(strcmp(n,G.adjList[i].vertex)==0)
        return i;
    }
    printf("没有找到相关顶点,图的信息有误!\n");
    return 0;
}
//输入图的相关信息  
ALGraph InPut(ALGraph G)
{
    int i;
    char haha[4];
    printf("请输入图的顶点数:");
    scanf("%d",&G.vexnum);
    printf("请输入图的所有顶点信息(如:v1 v2 v3):");
    for(i=0;i<G.vexnum;i++)
    {
        scanf("%s",G.adjList[i].vertex);
        G.adjList[i].link=NULL;
    }
    printf("请输入图的边数:");
    scanf("%d",&G.arcnum);
    printf("请输入图的所有边信息(如:v1,v2 v1,v3):\n");
    for(i=0;i<G.arcnum;i++)
    {
        scanf("%s",G.bian[i].one);
        scanf("%s",G.bian[i].two);
        gets(haha);
    }
    printf("输入完毕\n\n");
    return G;
}
//构成节点
void Jiedian(int n,int n1,ALGraph &G)
{
    ArcNode *p,*q;
    if(G.adjList[n].link==NULL)
    {
        q=(ArcNode *)malloc(sizeof(ArcNode));        //开辟 节点 空间
        if(!q)                                        //判断开辟节点 是否 成功
        {
            printf("节点生成错误!返回主函数\n");
            return;
        }
        q->adjvex=n1;            //节点数据赋值
        q->next=NULL;
        G.adjList[n].link=q;
    }
    else
    {
        p=G.adjList[n].link;
        q=(ArcNode *)malloc(sizeof(ArcNode));        //开辟 节点 空间
        if(!q)            //判断开辟节点 是否 成功
        {
            printf("节点生成错误!返回主函数\n");
            return;
        }
        q->adjvex=n1;
        q->next=NULL;
        if(p->next==NULL)
        {
            if(p->adjvex<q->adjvex)
            {
                p->next=q;
            }
            else
            {
                G.adjList[n].link=q;
                q->next=p;
                p->next=NULL;
            }
        }
        else
        {
            if(p->adjvex>q->adjvex)
            {
                q->next=p;
                G.adjList[n].link=q;                
            }
            else
            {
                while(p->next)
                {
                    if(p->next->adjvex>q->adjvex)
                    {
                        q->next=p->next;
                        p->next=q;
                        break;
                    }
                    p=p->next;
                }
                if(p->next==NULL)
                    p->next=q;
            }
        }
    }
    
}
//构成图的邻接表存储结构
void CreateMGraph(ALGraph &G)
{
    int i,one1,two1;
    for(i=0;i<G.arcnum;i++)
    {
        one1=PanDuan(G.bian[i].one,G);            //调用 函数
        two1=PanDuan(G.bian[i].two,G);            //调用 函数
        Jiedian(one1,two1,G);                //调用 函数
        Jiedian(two1,one1,G);                //调用 函数
    }
    printf("图的邻接表构成完毕!\n\n");
}
//输出图的邻接表存储信息
void OutPutMGraph(ALGraph &G)
{
    ArcNode *p;
    for(int i=0;i<G.vexnum;i++)
    {
        p=G.adjList[i].link;
        printf("%d|%s|",i,G.adjList[i].vertex);
        while(p)
        {
            printf("-->|%d|",p->adjvex);
            p=p->next;
        }
        if(p==NULL)
            printf("-->NULL\n");
    }
    printf("图的邻接表输出完毕!\n\n");
}
//输出图的深度优先遍历顺序
void DFS(int i,ALGraph &G)            //图的深度优先遍历的递归运算
{
    printf("%s ",G.adjList[i].vertex);
    visit[i]=1;
    ArcNode *p;
    p=G.adjList[i].link;
    while(p!=NULL)
    {
        if(G.adjList[i].link&&!visit[p->adjvex])
        {
            DFS(p->adjvex,G);
        }
        p=p->next;
    }
}
void DFStraversal(ALGraph &G)
{
    char haha[5];
    printf("请输入开始遍历的第一个结点向量: ");
    scanf("%s",haha);                            //输入  第一个 开始 遍历的节点
    printf("深度优先遍历的结果为:");
    for(int i=0;i<G.vexnum;i++)                    //这个for循环 是寻找 第一个开始 遍历的节点
    {
        if(strcmp(G.adjList[i].vertex,haha)==0)            //判断字符串 是否 相等
        {
            DFS(i,G);            //从 用户 输入的第一个 节点开始 遍历
            break;
        }
    }
    for(i=0;i<G.vexnum;i++)            //把 没有 输出来的 节点 输出来
    {
        if(visit[i]==0)            //判断 当前节点 是否已经 输出来了
        {
            DFS(i,G);      //没输出来的 节点 调用 DFS递归函数  
        }
    }
    printf("\n遍历完毕\n\n");
}
//退出
void TuiChu()
{
    printf("~谢谢使用~\n");
}
//主函数
int main()
{
    int choice;
    ALGraph G;
    while(true)                                //无限 使用 本程序
    {
        printf("********欢迎使用图的深度优先遍历程序********\n");   //用户界面
        printf("*****输入图的相关信息          请输入 1*****\n");
        printf("*****构成图的邻接表存储结构    请输入 2*****\n");
        printf("*****输出图的邻接表存储信息    请输入 3*****\n");
        printf("*****输出图的深度优先遍历顺序  请输入 4*****\n");
        printf("*****退出                      请输入 0*****\n");
        printf("请输入您的选择:");
        scanf("%d",&choice);
        if(choice>4||choice<0)                //异常判断   不要这个 也行
        {
            printf("请输入0~4之间的数字!请重新输入!\n\n");
            continue;
        }
        switch(choice)            //选择哪一个操作
        {
        case 1:        G=InPut(G);
            break;
        case 2:        CreateMGraph(G);
            break;
        case 3:        OutPutMGraph(G);
            break;
        case 4:        DFStraversal(G);
            break;
        case 0:        TuiChu();
            exit(0);
        }
    }
    return 0;

}


6.测试结果

6.1输入部分用户界面


图 6.1 输入部分用户界面

6.2生成邻接表用户界面


图 6.2生成邻接表用户界面

6.3输出邻接表信息用户界面


图 6.3输出邻接表信息用户界面

 

6.4深度优先遍历用户界面


图 6.4深度优先遍历用户界面

 

6.5退出部分用户界面


图 6.5退出部分用户界面



0 0
原创粉丝点击