考研数据结构--严版图相关代码 自用

自用,写的很乱


1、BFS


void BFSTraverse(Graph G,Status (*visit)(int v))
{
	for(int v = 0; v < G.vexNum; v++) visited[v] = false;
	InitQueue(Q);
	for(int v = 0; v < G.vexNum; v++)
	{
		if(!visited[v])
		{
			visited[v] = true; visited(v);
			EnQueue(Q, v);
			while(!QueueEmpty(Q))
			{
				int u;
				DeQueue(Q, u);
				for(int w = FirstAdjVex(G, u); w >= 0; w = NextAdjVex(G, u, w))
				{
					if(!visited[w])
					{
						visited[w] = true;
						visit(w);
						EnQueue(Q, w);
					}//if
				}//for
			}//while
		}//if
	}//for
} //BFSTraverse

2、DFS

bool visited[MAXSIZE];
Status (*visit)(int v); //函数变量

void DFSTraverse(Graph G)
{
	for(int v = 0; v < G.numVex; v++) visited[v] = false;
	for(int v = 0; v < G.numVex; v++)
	{
		if(visited[v] == false)
		{
			DFS(G, v);
		} 
	}
} 
void DFS(Graph G, int v)
{
	visited[v] = true;
	visit(v);
	for(int w = FirstAdjVex(G, v); w >= 0; w = NextAdjVex(G, v, w))
	{
		if(!visited[v]) DFS(G, v);
	}
}

3、DFS非递归(嫌麻烦,所以用C++写的,也不知道考试行不行)

#include<stack>
#include<iostream>
#include<vector>
using namespace std;

void DFS_Non_RC(AGraph &G, int v)
{
	int w;
	stack<int>stk;
	vector<bool>visited(G.vexnum, false);
	stk.push(v);
	visited[v] = true;
	while(!stk.empty())
	{
		int u = stk.top(); stk.pop();
		visit(u);
		for(w = FirstNeighbor(G, u); w >= 0; w = NextNeighbor(G, u, w))
		{
			if(!visited[w])
			{
				visited[w] = true;
				stk.push(w);
			}
		}
	} 
} 

4、用DFS创建生成树或生成森林(2021考的可能性很大)

typedef struct CSNode{
	int data;
	struct *CSNode *lchild, *nextSibling;
}CSNode, *CSTree;

bool visited[MAXSIZE];

void DFSForest(Graph G, CSTree &T)
{
	T = NULL;
	for(int v = 0; v < G.vexNum; v++)
	{
		visited[v] = false;
	}//for
	for(int v = 0; v < G.vexNum; v++)
	{
		if(!visited[v])
		{
			CSNode *p = (CSNode*)malloc(sizeof(CSNode));
			*p = (GetVex(G, v), NULL, NULL);
			if(!T) T = p;
			else q->nextSibling = p;
			q = p;
			DFSTree(G, v, p);
		}//if
	}//for
} //DFSForest
void DFSTree(Graph G, int v, CSTree &T)
{
	visited[v] = true; bool first = true;
	for(int w = FirstAdjVex(G, v); w >= 0; w = NextAdjVex(G,v,w))
	{
		if(!visited[w])
		{
			CSNode *= (CSNode*)malloc(sizeof(CSNode));
			*p = {GetVex(G, w), NULL, NULL};
			if(first)
			{
				T->lchild = p; first = false;
			} //if
			else
			{
				q->nextSibling = p;
			}//else
			q = p;
			DFSTree(G, w, q);
		}//if
	}//for
}//DFSTree 

5、prim


void MiniSpanTree_Prim(MGraph G,int u)
{
	struct{
		int adjvex;
		int lowcost; 
	}closeEdge[MAX_VERTEX_NUM];
	
	for(int i = 0; i < G.verNum; i++)
	{
		if(i != u)
		{
			closeEdge[i] = {u, G.arcs[u][i].adj};
		}
	}
	closeEdge[i].lowcost = 0;
	for(int i = 1; i < G.vexNum; i++)
	{
		int k = minimum(closeEdge);
		print(closeEdge[k].adjvex, G.vexs[k]); //输出生成树的边 vexs[]是顶点向量
		closeEdge[k].lowcost = 0;
		for(int j = 0; j < G.vexnum; j++)
		{
			if(G.arcs[k][j].adj < closeEdge[j].lowcost)
			{
				closeEdge[j] = {G.vexs[k], G.arcs[k][j].adj};
			}
		} 
	} 
} 
好记版本
typedef struct Gragh{ //图的定义 
	double matrix[MAXSIZE][MAXSIZE]; //邻接矩阵 
	char vertexs[MAXSIZE];
	int verNum; //顶点个数 
}Graph;

typedef struct{ //辅助数组类型 
	int src;
	int lowcost;
}Edge;

void prim(Graph g, int u)//第u个结点出发(从0开始编号) 
{
	
	Edge closeEdge[MAXSIZE]; 
	for(int i = 0; i < g.verNum; i++) //辅助数组初始化 
	{
		Edge t;
		t.src = u;
		t.lowcost = g.matrix[u][i]; 
		closeEdge[i] = t;
	} 
	closeEdge[u].lowcost = 0;  //初始, U={u} 
	for(int i = 1; i < g.verNum; i++) // 选择其他数组
	{
		int k = minimum(closeEdge);  //求出T的下一顶点:第k个顶点
		//此时 closeEdge[k].lowcost = min{closeEdge[vi].lowcost | closeEdge[vi].lowcost > 0, vi属于V-U}
		printf("%2d,%c",closeEdge[k].lowcost, g.vertexs[k]);
		closeEdge[k].lowcost = 0;   //第k顶点并入U集 
		for(int j = 0; j < g.verNum; j++) 
		{
			if(g.matrix[k][j] < closeEdge[j].lowcost)   //新顶点并入U后更新到U-V的最短距离 
			{
				Edge t;
				t.src = k;
				t.lowcost = g.matrix[k][j];
				closeEdge[j] = t; 
			}
		} 
	}	
}
与dijkstra相差一行代码的prim
#define VERTICE_MAXSIZE 100
#define INF 99999999
typedef struct MGraph{
	int edge[VERTICE_MAXSIZE][VERTICE_SIZE];
	char verticeList[VERTICE_MAXSIZE];  //顶点表 
	int n,e; // 顶点数、边数 
};
void prim(MGraph &G, int v, int lowcost[], int path[])
{
	int n = numberOfVertice(G);
	int S[VERTICE_MAXSIZE];
	for(int i = 0; i < n; i++)
	{
		dist[i] = G.edeg[v][i];
		S[i] = 0;
		if(i != v && dist[i] < INF) path[i] = v;
		else path[i] = -1; 
	} 
	S[v] = 1; dist[v] = 0;
	for(int i = 0; i < n - 1; i++)
	{
		int min = INF;
		int u = v; 
		for(int j = 0; j < n; j++)
		{
			if(!S[j] && dist[j] < min){	u = j;  min = dist[j];}
		} 
		S[u] = 1;   //u结点并入生成树 
		for(int k = 0; k < n; k++) //新结点并入生成树更新V-U中顶点到U的距离 
		{
			w = G.edge[u][k];
			if(!S[k] &&  w < dist[k])
			{//k是V-U中的结点 它到U的距离变短了 
				dist[k] = w; 
				path[k] = u;
			}
		}	
	}
}

===更新

二合一:

#define INF 9999999
void dijkstraOrPrim(Graph G, int start)
{
	bool close[N] = {false};
	int Min[N] = {INF};
	
	close[start] = true;
	Min[start] = 0;
	
	for(int i = 0; i < n-1; i++)
	{
		int k = -1;
		for(int j = 0; j < n; j++)
		{
			if(!close[j] && (k == -1 || Min[k] > Min[j])) k = j;
		}
		close[k] = true;
		for(int j = 0; j < n; j++)
		{
			//dijkstra
			if(Min[j] > Min[k]+G[k][j])
			{
				Min[j] = Min[k] + G[k][j];
			}
			/*
			//prime
			if(Min[j] > G[k][j])
			{
				Min[j] = Min[k] + G[k][j];
			}
			*/
		}
	}
	/*其余代码*/
} 

6、kruskal

版本1(殷人昆版)

typedef struct Edge{
	int src;
	int dest;
	int weight;
}Edge;

void kruskal(ALGraph &g) 
{//最小生成树的概念,算法只适用于无向图,有向图有其他的叫法 
	Edge w;   //临时边结点 
	UFSet ufset;  Initial(ufset);                        //建立并查集并初始化 
	minHeap heap;  Initial(heap);	                     //建立小根堆并初始化 
	int n = numberOfVertices(g), e = numberOfEdges(g);   //图的顶点数和边数 
	for(int i = 0; i < n; i++)  							//所有边插入小根堆 
	{
		for(int j = firstNeighbor(g, i); j >= 0; j = nextNeighbor(g, i, j));
		{
			if(i < j)
			{//无向图只用插入一半 
				w.src = i; 
				w.dest = j;
				w.weight = getWeight(g, i, j);
				insert(heap, w);                           //将边插入小根堆,小根堆以weight排序 
			}
		}
	}
	int countEdge = 0;
	int xroot, yroot;   
	while(!heapEmpty(heap))
	{
		Remove(heap, w);       //将小根堆堆顶的边赋值个w,并弹出
		xroot = Find(ufset, w.src);   //并查集中顶点src的根
		yroot = Find(ufset, w.dest);  //并查集中顶点dest的根
		if(xroot != yroot)        //两个顶点不在一个集合,可以加入最小生成树 
		{
			printf("%4d-->%4  weight%5d",w.src, w.dest, w.weight); //输出 
			Merge(w.src, w.dest);  //合并连通分量,使两者根一致 
			countEdge++; 
		} 
	}
	if(countEdge < n-1) printf("该图不连图,无最小生成树");	
}
版本2:c++版 基于邻接矩阵
class UFSet
{
public:
	int *parent;  //每个子集的根 
	int *rank;   //每个子集的秩 
	UFSet(int n)
	{
		parent = new int[n];
		rank = new int[n];
		for(int i = 0; i < n; i++)
		{
			parent[i] = i;
			rank[i] = 0;
		}
	} 
	int find(int x)
	{
		if(x != parent[x])
		{
			parent[x] = find(parent[x]); //路径压缩 
		}
		return parent[x];
	}
	void merge(int x, int y)
	{
		int xroot = find(x);
		int yroot = find(y);
		if(xroot == yroot){
			return ;
		} 
		if(rank[xroot] < rank[yroot])//按秩合并
		{
			parent[xroot] = yroot;
		}
		else if(rank[xroot] > rank[yroot])
		{
			parent[yroot] = xroot;
		}
		else
		{
			parent[yroot] = xroot;
		}
	} 
};
class Edge{
public:
	int src;
	int dest;
	int weight;
	Edge(int s,int d,int w)
	{
		src = s;
		dest = d;
		weight = w;
	}
};
typedef struct MGraph
{
	int matrix[MAXSIZE][MAXSIZE];
	int vertexNum, edges; 
}MGraph;

define INF 999999;

void kruskal(MGraph g) 
{
	UFSet ufset(g.vertexNum); //创建并查集,传入顶点个数
	Edge *edges = new Edge[g.edgeNum]; //创建边集
	int p = 0;
	for(int i = 0; i < g.vertexNum; i++)
	{
		for(int j = 0; j < g.vertexNum; j++)
		{
			if(g.matrix[i][j]> 0 && g.matrix[i][j] != INF)
			{
				edges[p] = Edge(i, j, g.matrix[i][j]);
			}
		}
	} 
	sort(edge, edge + g.edgeNum); //按权重进行排序
	int count = 0;
	for(int i = 0; i < g.edgeNum; i++)
	{
		x = ufset.find[edges[i].src];
		y = ufset.find[edges[i].dest];
		if(x != y)
		{
			ufset.merge(edges[i].src, edges[i].dest);
			printf("%3d-->%3d  weight:%5d",edges[i].src, edges[i].dest, edges[i].weight);
			count++;
		}
	} 
	if(count < g.vertexNum-1) printf("该图不连通,无最小生成树");
}
版本3
#include<iostream>
#include<vector>
#include<algorithm> 

using namespace std;
class Subset
{//并查集类 
public:
	int* parent;	//每个子集的根 
	int* rank;		//每个子集的秩 
	Subset(int n)
	{//构造函数初始化 
		parent = new int[n];
		rank = new int[n];
		for (int i = 0; i < n; i++)
		{
			parent[i] = i;
			rank[i] = 0;
		}
	}
	int find(int x)			//找x的root 
	{
		if (parent[x] != x) 
		{
			parent[x] = find(parent[x]);	//压缩路径 
		}
		return parent[x];
	}
	void unionSet(int x, int y)
	{//合并x合y所在的子集 
		int xroot = find(x);			 
		int yroot = find(y);
		if(xroot == yroot)
		{
			return ;
		}
		if (rank[xroot] < rank[yroot])
		{
			parent[xroot] = yroot;
		}
		else if (rank[xroot] > rank[yroot])
		{
			parent[yroot] = xroot;
		}
		else
		{
			parent[yroot] = xroot;
			rank[xroot]++;
		}
	}
};
class Edge
{
public:
	int src;		//起始顶点 
	int dest; 		//目标顶点 
	int weight;
	Edge(int _src, int _dest, int _weight)
	{
		src = _src;
		dest = _dest;
		weight = _weight;
	}
	Edge():src(0),dest(0),weight(0){}
	bool operator < (const Edge &b) const
	{//运算符重载 
		return weight < b.weight;
	} 
};

/* 
class cmp
{
public:
	bool operator () (Edge a, Edge b)		//从小到大排 
	{
		return a.weight < b.weight;
	}
};
*/ 
class Graph
{
public:
	int V;	//顶点数
	vector<Edge> edge;
	Graph(int v):V(v),edge(0){}

	void kruskal()
	{
		vector<Edge> result;	//存放最小生成树的路径 

		//cmp cmp1;
		//sort(edge.begin(), edge.end(),cmp1);
		sort(edge.begin(), edge.end());			//对所有边按权重从小到大排序 

		Subset subsets(V);		//创键并查集对象,V为顶点数 

		int i = 0;
		while (i < edge.size())	//处理所有的边 
		{
			int x = subsets.find(edge[i].src);
			int y = subsets.find(edge[i].dest);

			if (x != y)			//在不在同一个集合(连同分量) 
			{
				subsets.unionSet(x, y);
				result.push_back(edge[i]);
			}
			i++;
		}
		
		//输出最小生成树的边 
		vector<Edge>::iterator it;
		for (it = result.begin(); it != result.end(); it++)
		{
			cout << it->src << "-->" << it->dest <<" == "<<it->weight << endl;
		}
	}
};
int main()
{
	Graph g1(4);
	g1.edge.push_back(Edge(0, 1, 10));
	g1.edge.push_back(Edge(0, 2, 6));
	g1.edge.push_back(Edge(0, 3, 5));
	g1.edge.push_back(Edge(1, 3, 15));
	g1.edge.push_back(Edge(2, 3, 4));
	g1.kruskal();

	return 0;
}

7、从i到j是否有路径 //2020 848真题

#include<iostream>
#include<queue>
 
using namespace std;

int visited[MAXSIZE] = {0};
bool exit_path_dfs(ALGraph G,int i, int j)
{
	int p;
	if(i == j) return true;
	visited[i] = true;
	for(p = FirstNeighbor(G, i); p >= 0; p = NextNeighbor(G, i, p))
	{
		if(!visited[p] && exit_path_dfs(G,p,j))
		{
			return true;
		}
	}
	return false;
}

bool exit_path_bfs(ALGraph G, int i, int j)
{
	int visited[MAXSIZE] = {0};
	queue<int>q;
	q.push(i);
	int cur;
	while(!q. empty())
	{
		cur = q.front();
		q.pop();
		visited[cur] = true;
		for(int w = FirstNeighbor(G, i); w >= 0; w = NextNeighbor(G, i, cur))
		{
			if(w == j) return true;
			if(!visited[w])  q.push(w);
		}
	}
	return false;
}

8、打印u到v的所有简单路径

#define VERTEX_MAXSIZE 100
 
typedef struct ENode{
	int dest;
	struct ENode *next;
}ENode;

typedef struct VNode{
	char data;   
	struct ENode *adj;   //指向第一个邻接顶点 
}VNode;

typedef struct AGraph
{
	VNode adjList[VERTEX_MAXSIZE];
	int n, e;  //顶点数,边数 
}AGraph;
void print(char path[])
{
	//打印.........
}

void findPathUtil(AGraph G,int u, int v, bool visited[],char path[], int pos)
{
	int w, i;
	ENode *p;  
	visited[u] = true;
	if(u == v)
	{
		print(path);   //打印路径
		return ;  //简单路径,下面可以剪掉了
	}
	p = G.adjList[u].adj;  //p指向u的第一个邻接顶点
	while(p != NULL);
	{
		w = p->dest;
		if(visited[w] == false)
		{
			path[pos] = G.adjList[w].data;
			findPathUtil(G, w, v, visited, path, pos+1); 
		}
		p = p->next;
	} 
	visited[u] = false;
} 

void findPath(AGraph G,int u, int v)
{
	bool visited[VERTEX_MAXSIZE]={0};
	char path[VERTEX_MAXSIZE]= "\0"; 
	findPathUtil(G, u, v,visited, path, 0);
}

9、单源带权非负最短路径dijkstra算法:

版本1:
#define VERTICE_MAXSIZE 100
#define INF 99999999
typedef struct MGraph{
	int edge[VERTICE_MAXSIZE][VERTICE_SIZE];
	int n,e; // 顶点数、边数 
};
void shortestPath_DIJ(MGraph &G, int v, int dist[], int path[])
{
	int n = numberOfVertice(G);
	int S[VERTICE_MAXSIZE];
	for(int i = 0; i < n; i++)
	{
		dist[i] = G.edeg[v][i];
		S[i] = 0;
		if(i != v && dist[i] < INF) path[i] = v;
		else path[i] = -1; 
	} 
	S[v] = 1; dist[v] = 0;
	for(int i = 0; i < n - 1; i++)
	{
		int min = INF;
		int u = v;  //u指向具有最短路径的顶点
		for(int j = 0; j < n; j++)
		{
			if(!S[j] && dist[j] < min){	u = j;  min = dist[j];}
		} 
		S[u] = 1;
		for(int k = 0; k < n; k++)
		{
			w = G.edge[u][k];
			if(!S[k] && w < INF && dist[u] + w < dist[k])
			{
				dist[k] = dist[u] + w; 
				path[k] = u;
			}
		}	
	}
}
//输出
void printShortestPath(MGraph &G, int v, int dist[], int path[])
{
	printf("从顶点到[%c]到其他各顶点的最短路径为:\n",G.verticeList[v]);
	int n = numberOfVertices(G);
	int d[VERTICE_MAXSIZE];
	for(int i = 0; i < n; i++)
	{
		if(i != v)
		{
			int j = i, k = 0;
			while(j != v) { d[k++] = j; j = path[j]; }
			d[k++] = v;
			printf("到顶点[%c]的最短路径为:",G.verticeList[i]);
			while(k > 0) printf("%c  ", G.verticeList[d[k--]]);
			printf("    长度: %6d\n",dist[i]); 
		}
	} 
}

10、无向图从i到j存不存在长度为k的简单路径

版本1:严版课后习题答案 dfs
int exist_path_len(ALGraph G,int i, int j, int k)
{
	int visited[MAXSIZE]={0};
	return exist_path_len_util(G, i, j, k, visited); 
}
int exist_path_len_util(ALGraph G,int i, int j, int k,int visited[])
{
	
	if(i == j && k == 0) return 0;
	else if(k > 0)
	{
		visited[i] = 1;
		for(int w = firstNeighbor(G,i); w >= 0; w = nextNeighbor(G,i,w))
		{
			if(!visited[w] && exist_path_len_util(G, i, j, k-1, visited));
		}
		visited[i] = 0;
	}
	return 0;
}
版本2 BFS(错误示例, 写完发现错了)
int exist_path_len2(ALGraph G, int i, int j, int k)
{
	if(k < 0 || i < 0 || j < 0) return 0;
	InitQueue(Q);
	EnQueue(Q,i);
	int cur;
	int level;
	int visited[MAXSIZE] = {0};
	while(!QueueEmpty(Q))
	{
		DeQueue(Q,cur);
		visited[cur] = 0;
		level++;
		if(lever > k) return 0;
		for(int w = firstNeighbor(G, cur); w >= 0; w = nextNeighbor(G, cur, w))
		{
			if(level == k && w == j) return 1;
			if(!visited[w])
			{
				EnQueue(Q, w);
			}
		}
	}
	return 0;
}

12、拓扑排序

版本1:严版
 
typedef struct VNode { 
    VertexType  data;   
    ArcNode   *firstarc; 
} VNode, AdjList[MAX_VERTEX_NUM];

typedef struct ArcNode{  
    int  adjvex;   
    struct  ArcNode  *nextarc; 
    InfoType   *info;   
}ArcNode;

 typedef struct {  
     AdjList  vertices;  
     int   vexnum,  arcnum; 
     int   kind;         
 } ALGraph;

Status topologicalSort(ALGraph G)
{
	int indegree[VERTICE_MAXSIZE];
	FindInDegree(G, indegree);
	InitStack(S);
	for(int i = 0; i < G.vexnum; i++)
	{
		if(!indegree[i]) Push(S, i);
	}
	count = 0;
	while(!StackEmpty(S))
	{
		Pop(S); print(i, G.vertice[i].data);
		count++;
		for(p = G.vertices[i].firstarc; p != NULL; p = p->nextarc)
		{
			int k = p->adjvex;
			if(!(--indegree[k])) Push(S, k);			
		}
	}
	if(count < G.vexnum) return ERROR;
	else return OK;
} 
版本2:

#define maxsize 100

bool topologicalSort(Graph G,int topoArray[], int &k)
{//G为给定图,函数通过topoArray返回拓扑排序(若有),通过k返回topoArray中顶点个数
//若小于顶点个数则该图无拓扑排序 
	int S[maxsize]; int top = -1; //定义栈,存放入度为0的顶点
	int n = numberOfVertices(G);	//顶点个数 
	int* indegree = (int*)malloc(sizeof(int)*n);  //创建入度数组 
	getIndegree(G,indegree);   //计算给定图每个顶点的入度 
	for(int i = 0; i < n; i++)
	{
		if(indegree[i] == 0) S[++top] = i;    //入度为0的顶点入栈 
	} 
	int cur;
	k = 0;
	while(top > -1)
	{
		cur = S[top--];
		topoArray[k++] = cur;
		for(int w = firstNeighbor(G,cur); w >= 0; w = nextNeighbor(G,cur,w))
		{//扫描cur顶点的出边表 
			if((--indegree[w])==0) S[++top] = w;  //邻接顶点入度减一,减后该顶点入度为0则入栈 
		} 
	}
	if(k < n)
	{
		printf("给定图有环,无拓扑排序");
		return false;
	} 
	return true;
} 

12、关键路径

#define maxsize 100

bool topologicalSort(Graph G,int topoArray[], int &k)
{//G为给定图,函数通过topoArray返回拓扑排序(若有),通过k返回topoArray中顶点个数
//若小于顶点个数则该图无拓扑排序 
	int S[maxsize]; int top = -1; //定义栈,存放入度为0的顶点
	int n = numberOfVertices(G);	//顶点个数 
	int* indegree = (int*)malloc(sizeof(int)*n);  //创建入度数组 
	getIndegree(G,indegree);   //计算给定图每个顶点的入度 
	for(int i = 0; i < n; i++)
	{
		if(indegree[i] == 0) S[++top] = i;    //入度为0的顶点入栈 
	} 
	int cur;
	k = 0;
	while(top > -1)
	{
		cur = S[top--];
		topoArray[k++] = cur;
		for(int w = firstNeighbor(G,cur); w >= 0; w = nextNeighbor(G,cur,w))
		{//扫描cur顶点的出边表 
			if((--indegree[w])==0) S[++top] = w;  //邻接顶点入度减一,减后该顶点入度为0则入栈 
		} 
	}
	if(k < n)
	{
		printf("给定图有环,无拓扑排序");
		return false;
	} 
	return true;
}
bool criticalPath(Graph G)
{
	int n = numberOfVertices(G); 
	int *topoArray = (int*)malloc(sizeof(int)*n);
	int k = 0;
	if(!topologicalSort(G,topoArray,k)) return false;
	int *ve = (*int)malloc(sizeof(int)*n);   //ve[i]表示事件i最早开始时间 
	int *vl = (*int)malloc(sizeof(int)*n); 	 //vl[i]表示事件i最迟开始时间
	for(int i = 0; i < n; i++)
	{
		ve[i] = 0;
		vl[i] = INF;
	} 
	for(int i = 0; i < n-1; i++) //计算各事件最早开始时间 
	{
		int cur = topoArray[i];
		for(int w = firstNeighbor(G,cur); w >= 0; w = nextNeighbor(G,cur,w))
		{
			if(ve[cur] + getWeight(G,cur,w) > ve) 
				ve[w] = ve[cur] + getWeight(G,cur,w); 
		}
	} 
	vl[n-1] = ve[n-1]; 
	for(int i = n-2; i >= 0; i--)
	{//计算各事件最晚开始时间 
		int cur = topoArray[i];
		for(int w = firstNeighbor(G,cur); w >= 0; w = nextNeighbor(G,cur,w))
		{
			if(vl[w] - getWeight(G,cur,w) < vl[cur])   
				vl[cur] = vl[w] - getWeight(G,cur,w); 
		}
	}
	for(int i = 0; i < n; i++) //计算所有活动最早和最晚开始时间 
	{
		for(int w = firstNeighbor(G, i); w >= 0; w = nextNeighbor(G, i, w))
		{
			int ae = ve[i];   // <i,w>活动最早开始时间 
			int al = vl[w] - getWeight(G, i, w);   // <i,w>最晚开始时间
			char tag = (ae == ee)?'Y':'N';
			printf("%d->%d 持续时间:%d, 最早开始时间:%d,最晚开始时间:%d,\
			 是否是关键路径的一条边:", i,w,getWeight(G,i,w),ae,al,tag); 
		}
	} 
	return true;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据结构》(C语言版) 算法源码及运行演示系统使用说明 一、启动演示系统 双击演示系统应用程序文件“DS_VC_ALGO.EXE”启动演示系统,出现图1所示界面。 图1 《数据结构》(C语言版)算法源码及运行演示系统主界面 二、演示系统使用步骤 除了个别算法之外,演示系统给出了《数据结构》(C语言版)书中算法对应的程序代码(CPP文件)和测试运行程序(VC++6.0的EXE文件)。通过本系统,可以显示算法的源代码以及运行结果。具体操作步骤如下: 1.选择相应章 单击演示系统界面右侧章选择按钮。 例如,要选择第6章,则单击“第6章”选择按钮。 当相应章被选择后,窗口的右侧部分将列出本章的算法选择按钮。 例如,选择第6章后,窗口的右侧部分将显示第6章中的算法6.1-6.13和6.15的选择按钮。由于书中的算法6.14和6.16只是示意性算法,故未给出源码,其按钮上的文字为灰色,处于“无效”状态。 2.选择相应章中的算法 单击窗口右侧部分所列举的本章某个算法选择按钮,被选择的算法的源码将在窗口左侧空白区域中显示。对于较长的源码,单击显示区域后,可用键盘的光标键和翻页键浏览源码。 例如,选择了第6章中的算法6.5后界面如图2所示: 图2 选择算法6.5 3.运行测试程序 单击窗口上部的“运行”按钮,将弹出运行窗口,运行所选算法的测试程序。若运行按钮为灰色,表示该算法无单独测试程序。 例如,算法6.5的测试运行窗口如图3所示: 图3 测试运行窗口 测试运行说明: 测试运行窗口显示程序的执行过程及结果。若在显示过程中出现运行窗口无法正常演示的情况,只需调节运行窗口大小即可正常显示(调节最小化按钮或窗口最大化/还原按钮“ ”)。 三、退出演示系统 使用完毕后,单击窗口右上角关闭按钮“ ”退出演示系统。 四、测试程序示例 在《数据结构》的课程教学中,各抽象数据类型的设计与实现是重要的学习和实践环节。为此,本系统只给出了各算法源码的测试程序的可执行文件。在此,给出算法6.5的测试程序示例,以供参考。 算法6.5是中序遍历线索二叉树的非递归算法,要对其源码进行测试,可首先调用算法6.6及6.7建立中序线索二叉树。以下是测试程序的源码,相关类型和辅助函数定义在文件include06.h和include06.cpp中,此略。 // test0605.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "include06.h" // 相关类型和辅助函数的定义 BiThrTree pre; // 线索二叉树遍历辅助变量 #include "algo0607.cpp" // 算法6.7源码 #include "algo0606.cpp" // 算法6.6源码 #include "algo0605.cpp" // 算法6.5源码 int main(int argc, char* argv[]) { char gl_str[64]; BiThrTree T; BiThrTree Thrt; printf("*******************************************\n"); printf("* 《数据结构》(C语言版)蔚敏,吴伟民 *\n"); printf("* 算法6.5, 6.6 & 6.7 *\n"); printf("*******************************************\n"); srand((unsigned)time(NULL)); // 随机函数初始化 T=NULL; // 空二叉树T for (int pass=0; pass<5; pass++) { // 测试运行5次,第一次为空树 outBiThrTree(T,gl_str); // 以类广义表的形式输出二叉树T到gl_str printf("T = %s\n", gl_str); // 显示 pre = NULL; Status r = InOrderThreading(Thrt, T); // 算法6.6,6.7,中序线索化 printf("InOrderThreading(Thrt, T) : %s\n", (r) ? "OK" : "ERROR"); initVisitStr(); // 将visitStr清为空串 InOrderTraverse_Thr(Thrt, v

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值