#define INF ~(1 << (sizeof(int)*8 -1)) // 最大值
#define GRAPHMAXNUM 30 //图的顶点容量
typedef int VertexElempy; //顶点元素
typedef struct VERTEXNODE* pVertexNode; //顶点节点指针
typedef struct VERTEXNODE
{
VertexElempy vertex; //顶点
pVertexNode link; //关联
}VertexNode;
typedef struct LGRAPH{
pVertexNode nodes[GRAPHMAXNUM]; //顶点链表集合
int veNum; // 顶点数量
int adNum; // 关联数量
}LGraph;
/*
依赖:
顺序图-Graph;栈-Stack;
改进:
链表图-LGraph;
封装:
1.该节点是否被遍历
2.判断是否遍历完全
3.节点的顺序存储位置
优化:
1.去掉压栈空间 - 压入顶点地址 - 增加查找顶点位置函数
*/
void GraphDfs(Graph *graph)
{
if (!graph)
{
return ;
}
if (graph->veNum==0)
{
return ;
}
Stack *stack = StackInit();
int visit[GRAPHMAXNUM] = {0}; // 遍历情况
int endFlag = 1; // 结束标志
int p = 0; // 所处节点位置
int temp[GRAPHMAXNUM] = {0}; // 压栈空间
temp[p]=p;
StackPush(stack, &temp[p]);
printf("%d ",graph->vertexs[0]);
visit[0]=1;
for (;;)
{
// 判断遍历情况
endFlag = 1;
for (size_t i = 0; i < graph->veNum; i++)
{
if (!visit[i])
{
endFlag = 0;
}
}
if (endFlag)
{
printf("\n");
break;
}
for (size_t i = 0; i < graph->veNum; i++)
{
// 存在关系
if (graph->adjacents[p][i]!=INF)
{
// 关系顶点未被访问
if (!visit[i])
{
p = i;
temp[p] = p;
visit[p] = 1;
endFlag = 1;
StackPush(stack,&temp[p]);
printf("%d ",graph->vertexs[p]);
break;
}
}
}
// 变更为已访问顶点
if (!endFlag)
{
p = *(int *)StackPop(stack);
}
}
printf("\n");
}
/*
依赖:
Queue-队列 GraphVertexOn-查找顶点存储位置
问题:
能否使用递归实现?
*/
void GraphBfs(Graph *graph)
{
Queue *queue = queueInit();
VertexElempy p;
int visit[GRAPHMAXNUM] = {0};
queueIn(queue, &graph->vertexs[0]);
while (!queueIsEmpty(queue))
{
// 弹出队列
p = *(VertexElempy *)queueOut(queue);
visit[GraphVertexOn(graph, p)] = 1;
printf("%d ", p);
for (size_t i = 0; i < graph->veNum; i++)
{
// 未被访问,存在关联的顶点,存入队列
// 满足条件全部入栈
if (!visit[i] &&
graph->adjacents[GraphVertexOn(graph, p)][i] != INF)
{
queueIn(queue,&graph->vertexs[i]);
visit[i] = 1;
}
}
}
printf("\n");
}
int GraphShortyPath(Graph *graph)
{
int visit[GRAPHMAXNUM] = {0};
for (size_t j = 0; j < graph->veNum; j++)
{
GraphShortOne(graph, graph->vertexs[j], visit, j);
for (size_t i = 0; i < graph->veNum; i++)
{
visit[i]=0;
}
}
return 0;
}
int GraphShortOne(Graph *graph, VertexElempy vertex, int *visit, int num)
{
int endFlag = 1;
visit[num] = 1;
// 顶点遍历完全
for (size_t i = 0; i < graph->veNum; i++)
{
if (!visit[i])
{
endFlag = 0;
}
}
if (endFlag)
{
return 0;
}
for (size_t j = 0; j < graph->veNum; j++)
{
// 存在关联 关系顶点未被访问
if (!visit[j] && graph->adjacents[GraphVertexOn(graph, vertex)][j] != INF)
{
// 更新距离
for (size_t i = 0; i < graph->veNum; i++)
{
// 递归顶点 与 目标顶点数据不进行更新
if (i == num || i == j)
{
;
}
else
{
int a,b,c;
a = graph->adjacents[num][i];
b = graph->adjacents[j][i];
c = graph->adjacents[num][j];
if (b==INF)
{
continue;
}
graph->adjacents[num][i]=a>c+b?c+b:a;
}
}
visit[j] = 1;
GraphShortOne(graph,graph->vertexs[j],visit,num);
}
}
return 0;
}
08-05
05-02