图的深度优先遍历[非堆栈、堆栈实现]

/**/ /*
标题:<<系统设计师>>应试编程实例-[图程序设计]
作者:成晓旭
时间:2002年09月06日(16:30:00-17:16:00)
完成图的创建函数、顺序遍历函数
时间:2002年09月08日(21:30:00-22:35:00)
完成图的深度优先遍历函数[非堆栈、堆栈实现]
*/

#include
" stdio.h "
#include
" stdlib.h "

// 如:FROMHEAD=1,则用头插法;否则:则用尾插法
#define FROMHEAD1
/**/ /*
如:HASHEAD被定义,则各顶点的邻接点链中<带起始顶点>;
否则:各顶点的邻接点链中<不带起始顶点>;
*/

#define NODE_NUM5
#ifdefHASHEAD
// <带起始顶点>
int GraphNode[NODE_NUM][ 3 ] = ... {...{1,'A',4},...{2,'B',4},...{3,'C',5},...{4,'D',5},...{5,'E',3}} ;
int ConnectTable[] = ... {0,1,2,3,1,0,2,3,2,0,1,3,4,3,0,1,2,4,4,2,3} ;
#else
// <不带起始顶点>
int GraphNode[NODE_NUM][ 3 ] = ... {...{1,'A',3},...{2,'B',3},...{3,'C',4},...{4,'D',4},...{5,'E',2}} ;
int ConnectTable[] = ... {1,2,3,0,2,3,0,1,3,4,0,1,2,4,2,3} ;
#endif

// 邻接表中图各顶点结构类型定义
#define gVertexNodestructgVertexNode
gVertexNode
... {
intorder;//顶点在图中的序号
intdata;//顶点的数据域
gVertexNode*link;//指向顶点的下一个邻接顶点节点的指针
}
;
// 邻接表中图各顶点的遍历头节点结构类型定义
#define gHeadNodestructgHeadNode
gHeadNode
... {
intvcount;//邻接链表的节点数目[即当前顶点的邻接顶点个数]
//intorder;//顶点在图中的序号
intdata;//顶点的数据域
gVertexNode*firstnode;//指向邻接表的首顶点节点的指针
}
;
/**/ /*
创建以邻接表方式存储的图
参数描述:
gHeadNodeHeadNode图的邻接存储的头节点数组
intmax:图的顶点个数
intfromhead:插入邻接占点的方式
fromhead=1头插入方式
fromhead=0尾插入方式
*/

void CreateGraph(gHeadNodeHeadNode[], int max, int fromhead)
... {
gVertexNode
*p,*tail;//当前顶点节点及邻接表当前节点的邻接链表的尾节点
inti,j,k;//i,j为循环计数器,k为当前顶点的邻接顶点数目
for(i=0;i<max;i++)
...{
HeadNode[i].vcount
=GraphNode[i][2];
HeadNode[i].data
=GraphNode[i][1];
HeadNode[i].firstnode
=NULL;
//printf(" 顶点[%c]有[%d]个邻接点! ",HeadNode[i].data,HeadNode[i].vcount);
}

for(i=0,k=0;i<max;i++)
...{
for(j=0;j<HeadNode[i].vcount;j++)
...{
//创建图的顶点节点
p=(gVertexNode*)malloc(sizeof(gVertexNode));
if(p==NULL)
...{
exit(
1);
}

else
...{
//图的新顶点赋值
p->order=GraphNode[ConnectTable[k+j]][0];
p
->data=GraphNode[ConnectTable[k+j]][1];
p
->link=NULL;
if(fromhead)
...{//新节点放在最前面<紧接头节点的后面>头插法
p->link=HeadNode[i].firstnode;
HeadNode[i].firstnode
=p;
}

else
...{//新节点放在最后面<紧接最后一个表节点的后面>尾插法
if(HeadNode[i].firstnode==NULL)
...{//插入第一个节点
HeadNode[i].firstnode=p;
tail
=p;
}

else
...{//插入非第一个节点[直接接到最后一个节点之后]
tail->link=p;
tail
=p;
}

}


}

}

//移动关联表计数位置“指针”
k=k+HeadNode[i].vcount;
}

}

/**/ /*
顺序访问图中的各个节点[以创建的邻接表的头节点数组前后顺序]
参数描述:
gHeadNodeHeadNode图的邻接存储的头节点数组
intmax:图的顶点个数
*/

void Sequence_Journey(gHeadNodeHeadNode[], int max)
... {
gVertexNode
*p;
inti;
printf(
"以创建的邻接表的头节点数组前后顺序访问的图: ");
for(i=0;i<max;i++)
...{
p
=HeadNode[i].firstnode;
//printf(" 顶点[%c]的[%d]个邻接点: ",HeadNode[i].data,HeadNode[i].vcount);
while(p!=NULL)
...{
printf(
"顶点[%d][%c] ",p->order,p->data);
p
=p->link;
}

printf(
" ");
}

}

// 图的[深度优先遍历]算法<非堆栈实现算法>
void nsDeepthFirst_Journey(gHeadNodeHeadNode[], int max)
... {
gVertexNode
*p;//顶点
intvisited[NODE_NUM];//0:未访问1:已访问
inti;
printf(
"图的[深度优先遍历]结果<非堆栈实现>: ");
for(i=0;i<max;i++)//设置所有的顶点未访问标志
visited[i]=0;
for(i=0;i<max;i++)
...{
p
=HeadNode[i].firstnode;//指向当前访问顶点
//printf("顶点[%d][%c] ",p->order,p->data);
while(p!=NULL)//如果顶点有邻接顶点
...{
if(visited[p->order]==0)
...{//当前顶点的邻接顶点还未访问
printf("顶点[%d][%c] ",p->order,p->data);
visited[p
->order]=1;
}

p
=p->link;//移向下一个顶点
}

}

}

// 图的[深度优先遍历]算法<堆栈实现算法>
void DeepthFirst_Journey(gHeadNodeHeadNode[], int max)
... {
gVertexNode
*p;//顶点
gVertexNode*vstack[NODE_NUM+1];//顶点堆栈
intvisited[NODE_NUM+1];//0:未访问1:已访问
inti,top;//循环计数器和堆栈指针
printf("图的[深度优先遍历]结果<堆栈实现>: ");
for(i=0;i<=max;i++)//设置所有的顶点未访问标志
visited[i]=0;
for(i=0;i<max;i++)
...{
top
=1;
vstack[top]
=HeadNode[i].firstnode;//将本次访问的起始节点进栈,以便将来正确返回
while(top!=0)//堆栈不为空
...{
p
=vstack[top];//取堆栈中的栈顶元素
while((p!=NULL)&&(visited[p->order]==1))//还有邻接顶点,且已被访问
p=p->link;
if(p==NULL)//当前顶点没有邻接顶点,或有,但都已经被访问过
top--;//完成退栈
else
...{//否则,则访问之
printf("顶点[%d][%c] ",p->order,p->data);
visited[p
->order]=1;
vstack[
++top]=p;//访问顶点进栈
}

}

}

}

int main( int argc, char * argv[])
... {
gHeadNodeHeadNodeArray[NODE_NUM];
intInsertMode=-1;
while(InsertMode!=0&&InsertMode!=1)
...{
printf(
"请输入顶点的插入方式[0尾插入法:/1:头插入法]");
scanf(
"%d",&InsertMode);
}

CreateGraph(HeadNodeArray,NODE_NUM,InsertMode);
Sequence_Journey(HeadNodeArray,NODE_NUM);
//nsDeepthFirst_Journey(HeadNodeArray,NODE_NUM);
DeepthFirst_Journey(HeadNodeArray,NODE_NUM);
printf(
" 应用程序运行结束! ");
return0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值