图的基本操作代码

图的遍历

图的深度优先遍历

图的深度优先遍历主要分为递归和非递归两种方式
遍历的方式与书的先序遍历类似

1.递归的方式

bool visited[MAX_VERTEX_NUM];	//辅助函数


void DFSTraverse(Graph G){		//对图进行深度优遍历
	for(int v=0; v<G.vexnum ; v++)
		visited[v] = false;		//初始化辅助函数为0 or false
	
	for(int v=0; v<G.vexnum ; v++)	//开始进行深度遍历
		if(!visited[v])
			DFS(G,v);
}


void DFS(Graph G,int v){	//从顶点v出发进行深度遍历
	visit(v);				//访问v顶点
	visited[v] = true;		//设置标记已访问
	for(auto w = FirstNeighbor(G,v); w>=0 ; w = NextNeighbor(G,v,w))
		if(!visited[w])		//w为u的尚未访问的邻接顶点
			DFS(G,w);
}

2.非递归的方式

bool visited[MAX_VERTEX_NUM];	//辅助数组

void DFSTraverse(Graph G){		//图的深度遍历(非递归)
	for(int v=0;v<G.vexnum;v++)		visited[v] = false;		//初始化辅助数组
	for(int v=0;v<G.vexnum;v++)		//进行访问
		if(!visited[v])
			DFS(G,v);
}

void DFS(Graph G,int v){	//非递归方式进行访问
	Stack s;
	InitStack(s);
	posh(s,v);
	visited[v] = true;
	while(!Empty(s)){
		int w = pop(s);
		visit(w);
		for(int k = FirstNeighbor(G,w); k >= 0 ; k=NextNeighbor(G,w,k))
			if(!visited[k]){
				posh(s,k);
				visited[k] = true;
			}
	}

}

图的广度优先遍历

类似于树的层次遍历
需要构建队列进行辅助,达到广度优先遍历

bool visited[MAX_VERTEX_NUM];   //访问标记数组
Queue Q;
InitQueue(Q);

void BFSTraverse(Graph G){
    for (int i = 0; i<G.vexnum ; i++)
        visited[i] = false;
    
    for (int i = 0; i<G.vexnum ; i++)
        if(!visited[i])
            BFS(G,i);
}

void BFS(Graph G,int v){
    visited[v] = true;
    Enqueue(Q,v);
    while(!isEmpty(Q)){
        int k = Dequeue(Q);
        visit(G,k);
        for(int w = FirstNeighbor(G,k);w>=0;w = NextNeighbor(G,k,m))
            if(!visited[w]){
                visited[w] = true;
                Enqueue(Q,w)
            }
    }
}

拓扑排序

构造AOV网的拓扑序列的操作

在此主要分详细与简华Topo两种

详细Topo:

int Topo(const AdjGraph &G){
    stack<int> S;
    InitStack(S);

    int indegree[G.vexnum] = {0};
    arcNode *p;

    for(int i=0;i<G.vexnum;i++){
        p = G.adjlist[i].firstArc;
        while(p){
            indegree[p->adj]++;
            p = p->nextarc;
        }
    }


    for(int i=0;i<G.vexnum;i++)
        if(indegree[i]==0)  S.push(i);
    

    int count = 0;
    int u;
    while(!isEmpty(S)){
        u = S.pop();
        visit(u);
        count++;
        p = G.adjlist[u].firstArc;
        while(p){
            indegree[p->adj]--;
            if(indegree[p->adj]==0) S.push(p->adj);
            p=p->nextarc;
        }
    }

    if(count < G.vexnum)    return 0;   //有回路
    else    return 1;                   //无回路
}

简约Topo:

bool TopologicalSort(Graph G){
    InitStack(S);

    for(int i = 0;i<Graph.vexnum;i++){
        if(indegree[i]==0)
            push(S,i);
    }

    int count = 0;
    while(i(sEmpty(S)){
        Pop(S,i);
        visit(G,i);
        count++;

        for(p = G.vexlist[i].firstArc;p;p->nextarc){
            v = p->adjvex;
            if(!(--indegree[v]))
                Push(S,v);
        }
    }

    if(count<G.vexnum)  return false;   //排序失败
    else                return true;    //排序成功
}

关键路径

求一个AOE的关键路径主要分以下几个步骤:
第一步:求每个顶点(事件)V的最早开始时间ve; 计算公式为:ve(i) = MAX{ ve(j)+weight<j,i> }
第二步:求每个顶点(事件)V的最晚开始时间vl; 计算公式为:vl(j) = MIN{ vl(i)-weight<j,i> }
第三步:求每个边(活动)的最早开始时间; 计算公式为:e(a<j,i>) = ve(j)
第四步:求每个边(活动)的最早结束时间; 计算公式为:l(a<j,i>) = vl(i)-weight<j,i>
第五步:求每个边(活动)的时间余量; 计算公式为:l(i)-e(i)

基本描述代码如下:

p=Status CriticalPath(AdjGraph G){
    if(!TopologicalSort(G)) return false;   //如果有环图则返回false,没有关键路径

    for(int i=0; i<G.vexnum; i++){
        ve[i] = 0;
    }


    //求每个事件的最早开始时间
    for(int i=0; i<G.vexnum; i++){
        int k = Topo[i];
        
        AdjNode *p = G.vexlist[k].firstArc;
        while(!p){
            if(ve[i]+p->weight > ve[p->vex])
                ve[p->vex] = ve[i]+p->weight;
            p = p->nextarc;
        }
    }


    //求每个事件的最晚开始时间
    for(int i=0; i<G.vexnum; i++){
        vl[i] = ve[G.vexnum-1];
    }
    for(int i=G.vexnum ;i>=0;i--){
        int k = Topo[i];

        AdjNode *p = G.vexlist[k].firstArc;
        while(!p){
            if(vl[p->vex]-p->weight < vl[i])
                vl[i] = vl[p->vex] - p->weight;
            p = p->nextarc;
        }
    }



    //求关键路径
    for(int i=0; i<G.vexnum ; i++){
        AdjNode *p = G.vexlist[i].adjarc;
        while(!p){
            int e = ve[i];
            int l = vl[p->vex] - p->weight;
            if(e==l){
                printf("<%,%>\n",i,p->vex);
            }

            p = p->nextarc;

        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值