无向图的深度优先搜索(最终版)

本文介绍了一种实现无向图邻接多表的方法,并通过深度优先搜索(DFS)遍历输出顶点。文章详细展示了如何利用C语言构建邻接表,并通过实例演示了整个过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【实验内容】

设无向图G有n个点e条边,写意算法建立G的邻接多表,并按照深度优先搜索输出顶点,要求该算法时间复杂性为O(n+e),且除邻接多表本身所占空间之外只用O(1)辅助空间。


【参考方法】

邻接表定义:

#include<stdio.h>
#include<stdlib.h>
#define max 30

typedef struct edgenode{
    int adjvex;   
    char info;
    struct edgenode *next;
};

typedef struct vexnode{
    char data;     
    struct edgenode *link;      
}adjlist[max];


题目分析:

1、此题主要需要的是对邻接表的创建和遍历的理解,在要求上事实上比较简单。(笔者一共花了3小时不到就做完了)但是题目给的“邻接表定义”说实话有点乱,笔者在代码中还是按照自己的想法写了。

2、之后笔者又花了半个小时的时间对代码进行的进一步修改:由于是无向图所以一条边要增加两个结点,另外也是修改了一个小bug。并且也使用了更复杂的数据来测试。

3、做邻接表的遍历,做题者对递归需要有一定的理解,否则会觉得很难。

4、由于要改变指针所指向的值,所以用到了双重指针。

5、由于此题还是要用到递归,使用C++比较麻烦,所以选用C来写。(在申请空间的时候还是用到了new)

6、笔者由于要调试,所以用的编译器是visual c++,使用codeblocks的读者在运行代码的时候需要在for中给i定义。



效果:



 

#include<stdio.h>
#include<iostream>
#define Max 30
using namespace std;

typedef struct edgenode{
    int adjvex;     //指向的顶点的下标
    struct edgenode *next;//指向下一条边的指针
}edgenode;

typedef struct vexnode{
    char data;      //顶点的权值
    struct edgenode *link;      //指向一条与该顶点相连的边的指针
}vexnode;

typedef struct Graph{
    vexnode xlist[Max];
    int vexnum,edgenum;
}Graph;

void CreateGraph(Graph &g)
{
    printf("请输入顶点的个数:");
    scanf("%d",&g.vexnum);
	for(int i=0;i<g.vexnum;i++)//把与顶点相连的边设为空
		g.xlist[i].link=NULL;
    printf("请输入边的个数:");
    scanf("%d",&g.edgenum);
    printf("请输入各个顶点的值:(顶点之间用空格分离)\n");
	getchar();
    for(i=0;i<g.vexnum;i++)
    {
        g.xlist[i].data=getchar();
        getchar();
    }
    printf("请输入各个边的值:(形式如a-b,各边之间用空格分离)\n");
    for(i=0;i<g.edgenum;i++)
    {
        char tail,head;
        int tail_num=-1,head_num=-1;
        tail=getchar();
        getchar();
        head=getchar();
        getchar();

        //查找边的两个结点的下标
        for(int i=0;i<g.vexnum;i++)
        {
            if(g.xlist[i].data==tail)
                tail_num=i;
            if(g.xlist[i].data==head)
                head_num=i;
            //如果两者都已经找到那么就退出循环
            if(tail_num!=-1&&head_num!=-1)
                break;
        }
		
		//由于是无向图,所以要添加两个结点
		int t=2;
		while(t--)
		{
        //创建新的边结点并且赋值
        edgenode *s;
        s=new edgenode;
        s->adjvex=head_num;
        s->next=NULL;

		//由于要改变指针所指向的值,所以要用双重指针
		// 一直到next_node的值为空才给他赋值
		//避免新的边覆盖之前的边
		edgenode **next_node=&g.xlist[tail_num].link;
		while(*next_node)
		{
			next_node=&((*next_node)->next);
		}
		*next_node=s;
		
		//交换顶点位置,进入下一个循环
		int swap;
		swap=tail_num;
		tail_num=head_num;
		head_num=swap;
		
		}
    }
}

//定义一个bool数组来查看顶点是否被遍历过
static bool visited[Max];
//由于在PrintGraph中会用到递归,所以要先声明
void DFS(Graph g,int i);

void PrintGraph(Graph g)
{
    for(int i=0;i<g.vexnum;i++)
    visited[i]=false;

	printf("深度优先搜索输出的顶点的值分别为:\n");
    for(i=0; i<g.vexnum; i++)
        if(!visited[i])
            DFS(g,i);
	printf("\n");
}

void DFS(Graph g,int i)
{
    visited[i]=true;//标记已经遍历过
    printf("%c ",g.xlist[i].data);

	//nextNode来代表下一个相关边
    edgenode *nextNode=g.xlist[i].link;
	//如果下一个相关边不为空且没有遍历过
    while(nextNode)
    {
		if(!visited[nextNode->adjvex])
			DFS(g,nextNode->adjvex);

        nextNode=nextNode->next;
    }
		
}

int main()
{
    Graph g;
    CreateGraph(g);
	printf("\n");
	PrintGraph(g);
	printf("\n");

    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值