京公网安备 11010802034615号
经营许可证编号:京B2-20210330
图的深度优先遍历演示系统:
http://sjjg.js.zwu.edu.cn/SFXX/sf1/sdyxbl.html
===============
最后,咱们再来看深度优先搜索的递归实现与非递归实现
1、DFS 递归实现:
void dftR(PGraphMatrix inGraph)
{
PVexType v;
assertF(inGraph!=NULL,"in dftR, pass in inGraph is null/n");
printf("/n===start of dft recursive version===/n");
for(v=firstVertex(inGraph);v!=NULL;v=nextVertex(inGraph,v))
if(v->marked==0)
dfsR(inGraph,v);
printf("/n===end of dft recursive version===/n");
}
void dfsR(PGraphMatrix inGraph,PVexType inV)
{
PVexType v1;
assertF(inGraph!=NULL,"in dfsR,inGraph is null/n");
assertF(inV!=NULL,"in dfsR,inV is null/n");
inV->marked=1;
visit(inV);
for(v1=firstAdjacent(inGraph,inV);v1!=NULL;v1=nextAdjacent(inGraph,inV,v1))
//v1当为v的邻接点。
if(v1->marked==0)
dfsR(inGraph,v1);
}
2、DFS 非递归实现
非递归版本---借助结点类型为队列的栈实现
联系树的前序遍历的非递归实现:
可知,其中无非是分成“探左”和“访右”两大块访右需借助栈中弹出的结点进行.
在图的深度优先搜索中,同样可分成“深度探索”和“回访上层未访结点”两块:
1、图的深度探索这样一个过程和树的“探左”完全一致,
只要对已访问过的结点作一个判定即可。
2、而图的回访上层未访结点和树的前序遍历中的“访右”也是一致的.
但是,对于树而言,是提供rightSibling这样的操作的,因而访右相当好实现。
在这里,若要实现相应的功能,考虑将每一个当前结点的下层结点中,如果有m个未访问结点,
则最左的一个需要访问,而将剩余的m-1个结点按从左到右的顺序推入一个队列中。
并将这个队列压入一个堆栈中。
这样,当当前的结点的邻接点均已访问或无邻接点需要回访时,
则从栈顶的队列结点中弹出队列元素,将队列中的结点元素依次出队,
若已访问,则继续出队(当当前队列结点已空时,则继续出栈,弹出下一个栈顶的队列),
直至遇到有未访问结点(访问并置当前点为该点)或直到栈为空(则当前的深度优先搜索树停止搜索)。
将算法通过精简过的C源程序的方式描述如下:
//dfsUR:功能从一个树的某个结点inV发,以深度优先的原则访问所有与它相邻的结点
void dfsUR(PGraphMatrix inGraph,PVexType inV)
{
PSingleRearSeqQueue tmpQ; //定义临时队列,用以接受栈顶队列及压栈时使用
PSeqStack testStack; //存放当前层中的m-1个未访问结点构成队列的堆栈.
//一些变量声明,初始化动作
//访问当前结点
inV->marked=1; //当marked值为1时将不必再访问。
visit(inV);
do
{
flag2=0;
//flag2是一个重要的标志变量,用以、说明当前结点的所有未访问结点的个数,两个以上的用2代表
//flag2:0:current node has no adjacent which has not been visited.
//1:current node has only one adjacent node which has not been visited.
//2:current node has more than one adjacent node which have not been visited.
v1=firstAdjacent(inGraph,inV); //邻接点v1
while(v1!=NULL) //访问当前结点的所有邻接点
{
if(v1->marked==0) //..
{
if(flag2==0) //当前结点的邻接点有0个未访问
{
//首先,访问最左结点
visit(v1);
v1->marked=1; //访问完成
flag2=1; //
//记录最左儿子
lChildV=v1;
//save the current node's first unvisited(has been visited at this time)adjacent node
}
else if(flag2==1) //当前结点的邻接点有1个未访问
{
//新建一个队列,申请空间,并加入第一个结点
flag2=2;
}
else if(flag2==2)//当前结点的邻接点有2个未被访问
{
enQueue(tmpQ,v1);
}
}
v1=nextAdjacent(inGraph,inV,v1);
}
if(flag2==2)//push adjacent nodes which are not visited.
{
//将存有当前结点的m-1个未访问邻接点的队列压栈
seqPush(testStack,tmpQ);
inV=lChildV;
}
else if(flag2==1)//only has one adjacent which has been visited.
{
//只有一个最左儿子,则置当前点为最左儿子
inV=lChildV;
}
else if(flag2==0)
//has no adjacent nodes or all adjacent nodes has been visited
{
//当当前的结点的邻接点均已访问或无邻接点需要回访时,则从栈顶的队列结点中弹出队列元素,
//将队列中的结点元素依次出队,若已访问,则继续出队(当当前队列结点已空时,
//则继续出栈,弹出下一个栈顶的队列),直至遇到有未访问结点(访问并置当前点为该点)或直到栈为空。
flag=0;
while(!isNullSeqStack(testStack)&&!flag)
{
v1=frontQueueInSt(testStack); //返回栈顶结点的队列中的队首元素
deQueueInSt(testStack); //将栈顶结点的队列中的队首元素弹出
if(v1->marked==0)
{
visit(v1);
v1->marked=1;
inV=v1;
flag=1;
}
}
}
}while(!isNullSeqStack(testStack));//the algorithm ends when the stack is null
}
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
指标体系是企业数字化分析、业务监控、经营决策的核心基础框架,是将零散数据转化为可衡量、可对比、可落地业务价值的关键体系。 ...
2026-10-08随着市场竞争日趋饱和,同质化低价竞争逐渐陷入内卷僵局,传统以价格、渠道、促销为核心的营销模式边际效益持续递减。在此背景下 ...
2026-10-08 很多数据分析师画过趋势图、做过业绩预测,但当被问到“这个月销售额增长20%,到底是长期趋势自然增长,还是促销活动的短期 ...
2026-10-08你有没有想过,手机里点外卖、刷社交软件、转一笔账,背后到底是谁在替你"记着账"? 答案其实很简单:数据库,以及跟它对话的那 ...
2026-10-07CDA数据分析师 出品 作者:李诗怡 一、数据分析四大思维 1. 对比思维:没有对比就没有分析 核心观点:单独一个数字没有意义,有 ...
2026-10-05Kimball 是方法,星型模型是它产出的形状。 很多人把"Kimball vs 星型模型"当成一道选择题——这本身就是个误会:Kimball 是动词 ...
2026-10-05写在开头 老板在微信上甩来一句: "帮我看下为什么销量跌了。" ” 你回工位,打开 SQL,开始写。查订单表、拉近三个月、按 ...
2026-10-03CDA数据分析师 出品 作者:李诗怡 1. 事实表 vs 维度表 对比维度 事实表 维度表 核心问题 记录“业务发生了什么事” 描述 ...
2026-10-02做数据聚合时,PySpark的groupBy()确实能完成统计,这也是它的本职工作。但它有一个根本性局限:每一组数据,最终只能返回一行 ...
2026-10-01热力地图是数据可视化中极具辨识度与实用性的空间分析图表,结合地理空间维度与数据密度特征,通过颜色深浅、色阶渐变直观展示数 ...
2026-09-30 很多数据分析师做过按月份的销售额趋势图,画过按天的流量折线图,但当被问到“时间序列和普通数据有什么本质区别”“季节性 ...
2026-09-30同样是“银行数据岗”,在国有大行总行数据中心、在一家城商行的零售部、在银行系金融科技子公司、在保险公司,工作内容、成长节 ...
2026-09-29在数据分析与统计学研究中,数据往往不是独立存在的,不同变量之间普遍存在相互关联、相互影响的关系。相关性统计分析是挖掘变量 ...
2026-09-29 导读:大多数人只把 dataclasses 当成偷懒工具,用来少写 __init__、__repr__ 这类魔法方法。但它的能力远不止于此。本文带 ...
2026-09-29 很多数据分析师能熟练地计算指标、搭建标签体系,但当被问到“画像到底在解决什么问题”“画像和标签是什么关系”“画像如何 ...
2026-09-29在MySQL数据库运维与业务开发中,行业普遍存在“数据达到千万级就必须分表”的说法。但在实际生产环境中,千万条数据并不是强制 ...
2026-09-28CDA数据分析师 出品 作者:李诗怡 1. 5W1H 分析法 定义:经典系统性思维框架,通过六个核心维度对问题进行全方位拆解与剖析,确 ...
2026-09-28 很多分析师在设计标签时思路清晰,但真到落地环节却面临“数据在手,不知如何转化为可用标签”的困境:或因加工方式选择不当 ...
2026-09-28CDA数据分析师 出品 作者:李诗怡 1. 用户标签体系 定义: 通过一系列高度精炼的特征标识,对用户属性、行为与偏好进行量化刻画 ...
2026-09-24Pandas是Python生态中用于表格数据处理的核心库,广泛应用于数据清洗、统计运算、报表输出、数据分析建模等场景。在处理极大数值 ...
2026-09-24