实验内容:
1、键盘输入数据,建立一个有向图的邻接表。
2、输出该邻接表。
3、在有向图的邻接表的基础上计算各顶点的度,并输出。
4、以有向图的邻接表为基础实现输出它的拓扑排序序列。
5、采用邻接表存储实现有向图的深度优先递归遍历。
*6、采用邻接表存储实现有向图的广度优先遍历(利用队列实现)。
7、编写一个主函数,调试上述算法。
代码:
#include
#include
#include
#include
#include
#define INFMAX 9999999
#define MAXVEX 200
using namespace std;
typedef char VertexType;
typedef int EdgeType;
int visited[INFMAX];
typedef struct EdgeNode /* 边表结点 */
{
int adjvex; /* 邻接点域,存储该顶点对应的下标 */
EdgeType info; /* 用于存储权值,对于非网图可以不需要 */
struct EdgeNode *next; /* 链域,指向下一个邻接点 */
}EdgeNode;
typedef struct VertexNode /* 顶点表结点 */
{
VertexType data; /* 顶点域,存储顶点信息 */
EdgeNode *firstedge;/* 边表头指针 */
}VertexNode, AdjList[MAXVEX];
typedef struct
{
AdjList adjList;
int numNodes,numEdges; /* 图中当前顶点数和边数 */
}GraphAdjList;
void CreateALGraph(GraphAdjList *G)
{
int i,j,k,weight;
EdgeNode *e;
cout<<"输入顶点数和边数:";
cin>>G->numNodes>>G->numEdges; /* 输入顶点数和边数 */
for(i = 0;i < G->numNodes;i++) /* 读入顶点信息,建立顶点表 */
{
cout<<"请输入顶点信息:";
cin>>G->adjList[i].data; /* 输入顶点信息 */
G->adjList[i].firstedge=NULL; /* 将边表置为空表 */
}
for(k = 0;k < G->numEdges;k++)/* 建立边表 */
{
cout<<"输入边(vi,vj)上的顶点序号:";
cin>>i>>j; /* 输入边(vi,vj)上的顶点序号 */
e=(EdgeNode *)malloc(sizeof(EdgeNode)); /* 向内存申请空间,生成边表结点 */
e->adjvex=j; /* 邻接序号为j */
e->next=G->adjList[i].firstedge; /* 将e的指针指向当前顶点上指向的结点 */
G->adjList[i].firstedge=e; /* 将当前顶点的指针指向e */
//e=(EdgeNode *)malloc(sizeof(EdgeNode)); /* 向内存申请空间,生成边表结点 */
// e->adjvex=i; /* 邻接序号为i */
// e->next=G->adjList[j].firstedge; /* 将e的指针指向当前顶点上指向的结点 */
// G->adjList[j].firstedge=e; /* 将当前顶点的指针指向e */
}
}
void DispGraphAdjList(GraphAdjList *G)
{
int i;
EdgeNode *p;
cout<<"有向图的邻接表表示如下:"< printf("%6s%6s%12s\n","编号","顶点","相邻边编号"); for(i=0;i< G->numNodes;i++) { printf("%4d %6c",i,G->adjList[i].data);// for(p=G->adjList[i].firstedge;p!=NULL;p=p->next) printf("%4d",p->adjvex); cout< } } void DepthFirstSearch(GraphAdjList G,int v){ EdgeNode *p; cout< visited[v]=1; p=G.adjList[v].firstedge; while(p!=NULL){ if(!visited[p->adjvex]) DepthFirstSearch(G,p->adjvex); p=p->next; } } void DFSTraveGraph(GraphAdjList G){ int v; for(v=0;v visited[v]=0; } for(v=0;v if(!visited[v]) DepthFirstSearch(G,v); } } void calculator(GraphAdjList G)//有向图各节点的度 { EdgeNode *p; int num1,num2; cout<<"有向图邻接表的各节点度输出显示为:"< for(int i=0;i { num1=0; cout< p=G.adjList[i].firstedge; while(p)//计算出度 { num1++; p=p->next; } cout<<"出度为:"< num2=0; for(int j=0;j { if(i!=j) { p=G.adjList[j].firstedge; while(p) { if(p->adjvex==i) { num2++; break; } p=p->next; } } } cout<<"入度为:"< cout<<"度为:"< } } int *getInDegree(GraphAdjList *g) { int *inDegreeArray = (int *) malloc(g->numNodes * sizeof(int)); memset(inDegreeArray, 0, g->numNodes * sizeof(int)); int i; EdgeNode *pCrawl; for(i = 0; i < g->numNodes; i++) { pCrawl = g->adjList[i].firstedge; while(pCrawl) { inDegreeArray[pCrawl->adjvex]++; pCrawl = pCrawl->next; } } return inDegreeArray; } void topologicalSort(GraphAdjList *g) { int *inDegreeArray = getInDegree(g); //Stack * = initStack(); stack int i; for(i = 0; i < g->numNodes; i++) { if(inDegreeArray[i] == 0) zeroInDegree.push(i); } EdgeNode *pCrawl; while(!zeroInDegree.empty()) { i = zeroInDegree.top(); zeroInDegree.pop(); //printf("vertex %d\n", i); cout<
pCrawl = g->adjList[i].firstedge; while(pCrawl) { inDegreeArray[pCrawl->adjvex]--; if(inDegreeArray[pCrawl->adjvex] == 0) zeroInDegree.push(pCrawl->adjvex); pCrawl = pCrawl->next; } } } int main(void) { GraphAdjList G; CreateALGraph(&G); DispGraphAdjList(&G); calculator(G); cout<<"有向图的深度优先递归遍历为:"< DFSTraveGraph(G); cout<<"有向图的拓扑排序序列为:"< topologicalSort(&G); return 0; } 测试截图: