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

【实验内容】

设无向图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;
}


 

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现无向图的深度优先生成树主要分为以下几个步骤: 1. 定义的结构体,包含顶点数和边的数组(每个边包含起点和终点的编号)。 ``` struct Graph { int V; // 顶点数 vector<pair<int,int>> edges; // 边的数组 }; ``` 2. 定义一个DFS函数,用于遍历并生成深度优先生成树。该函数需要传入当前节点编号、父节点编号、当前生成树的深度、以及一个visited数组用于记录已经遍历过的节点。 ``` void DFS(int v, int parent, int depth, vector<bool>& visited, vector<vector<int>>& adj_list, vector<int>& parent_list, vector<int>& depth_list) { visited[v] = true; parent_list[v] = parent; depth_list[v] = depth; for (auto u : adj_list[v]) { if (!visited[u]) { DFS(u, v, depth + 1, visited, adj_list, parent_list, depth_list); } } } ``` 3. 定义一个函数来生成深度优先生成树。该函数需要传入一个结构体,以及一个起点编号。首先,需要初始化visited、parent_list和depth_list数组。然后,从起点开始调用DFS函数进行遍历,最终返回生成树的parent_list和depth_list数组。 ``` pair<vector<int>, vector<int>> DFS_tree(Graph& g, int start) { vector<bool> visited(g.V, false); vector<vector<int>> adj_list(g.V); vector<int> parent_list(g.V, -1); vector<int> depth_list(g.V, 0); // 构造邻接表 for (auto edge : g.edges) { int u = edge.first, v = edge.second; adj_list[u].push_back(v); adj_list[v].push_back(u); } // 生成深度优先生成树 DFS(start, -1, 0, visited, adj_list, parent_list, depth_list); return make_pair(parent_list, depth_list); } ``` 以上就是实现无向图的深度优先生成树的步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值