拓扑排序实验报告

时间:2024.3.31

数学与计算机学院 数据结构 实验报告

年级 09数计 学号 2009432125 姓名 刘宝 成绩 专业 数电 实验地点 主楼401 指导教师 苗秀芬 实验项目 拓扑排序 实验日期 10年12月24日

一、实验目的

1掌握图的存储结构及其基本操作,学会定义图的邻接表存储结构,并能在实际问题中灵活运用。

2掌握拓扑排序算法。

3、通过本实验的具体应用实例,灵活运用拓扑排序并进一步巩固队列/栈的运用。

二、实验问题描述

1简介:用邻接表形式存储实验中的有向无环图,此有向无环图称为:AOV网,若网中每一个顶点都在他的拓扑排序中,则说明不存在环。

2步骤:

?从AOV网中选出一个没有前驱的结点,并输出他;

?从网中删除此结点,并且删除从该顶点发出的所有有向边(邻接点的入度-1) ?重复以上两步,直到途中不存在入度为0的顶点为止

三、实验步骤

1、实验问题分析

(1) 顶点表

typedef struct//顶点表结点

{

int in;//入度

int vertex;//顶点域

edgenode * firstedge;//边表头指针

}vertexnode;

(2) 边表

typedef struct node //边表结点

{

int adjvex;//邻接点域

struct node * next;//指向下一个邻接点的指针域 }edgenode;

(3) 以邻接表类型存储的图类型

typedef struct{

Adjlist adjlist; //邻接表

int vnum,Enum; //顶点数和边数

}Algraph;

2、功能(函数)设计

(1)建立一个以邻接表存储的有向图

函数原型:

void creatalgraph(Algraph *G)

(2)拓扑排序

函数原型:

void TopoSort(Algraph *G)

四、实验结果(程序)及分析

1、 实验主要模块代码(带注释!)或模块的流程图

(1) 建立一个以邻接表存储的有向图

void creatalgraph(Algraph *G)//创建邻接链表

{

int i,k,j;

edgenode *s;

cout<<"该AOV网的顶点数和边数:"<<endl;

cin>>G->vnum>>G->Enum; //读入顶点数和边数

cout<<"请输入顶点信息:"<<endl;

for(i=0;i<G->vnum;i++) //建立有vnum个顶

点的顶点表

{

cin>>G->adjlist[i].vertex; //读入顶点信息

G->adjlist[i].in=0;

G->adjlist[i].firstedge=NULL; //顶点

的边表头指针设为空

}

cout<<"请输入边的信息:"<<endl; //

for(k=0;k<G->Enum;k++) //建立边表

{

cout<<"依次输入每一条边:"<<endl;

cout<<"从";cin>>i;cout<<"邻接到";cin>>j;cout<<endl;

//读入边<vi,vj>的顶点对应的序号

s=new edgenode; //生成新的边表结点

s->adjvex=j; //邻接点的序号为j

s->next=G->adjlist[i].firstedge; //将

新边表结点s插入到顶点vi的边表头部

G->adjlist[i].firstedge=s; }

}

(2) 拓扑排序

int toposort(Algraph *G)

{

int i,j,k;

int m=0,top;

edgenode *ptr;

top=-1;

for(i=0;i<G->vnum;i++)

if(G->adjlist[i].in==0)

{ G->adjlist[i].in=top;

top=i;}

while(top!=-1)

{

j=top;

top=G->adjlist[top].in;

cout<<G->adjlist[j].vertex<<endl;

m++;

ptr=G->adjlist[j].firstedge;

while(ptr!=NULL)

{

k=ptr->adjvex;

G->adjlist[k].in--;

if(G->adjlist[k].in==0){

G->adjlist[k].in=top;

top=k;

}

ptr=ptr->next; //头插入

}

}

if(m<G->vnum)

{

cout<<"此图中存在环!无法进行拓扑排序"<<endl;

return 0;//返回错误代码0

}

else

return 1;//成功返回1

}

2、测试数据

3、调试过程中出现的问题以及解决策略


第二篇:数据结构-拓扑排序-实验报告与代码


实验报告七----拓扑排序

一.需求分析

1、采用邻接表法的存储结构来定义有向图

2、实现有向图的创建、遍历

3、实现栈的创建及其基本操作(进栈、退栈、判空)

4、求图中顶点的入度

二.算法设计

本程序中采用的数据模型,用到的抽象数据类型的定义,程序的主要算法流程及各模块之间的层次调用关系

拓扑排序的基本思想是以下两点:

1、在有向图中选一个没有前驱的顶点且输出之。

2、从图中删除该顶点何所有以它为尾的弧。

3、 查邻接表中入度为零的顶点,并进栈。当栈为空时,进行

拓扑排序。

(a)退栈,输出栈顶元素V。

(b)在邻接表中查找Vj的直接后继Vk,将Vk的入度减

一,并令入度减至零的顶点进栈。

4、重复上述两步,直至全部顶点均已输出。如每输出完,则证明有环。

程序基本结构:

数据结构拓扑排序实验报告与代码

设定栈的抽象数据类型定义:

ADT Stack {

数据对象:D={|∈CharSet,i=1,2,3,…..,n,n>=0;}

数据关系:R={< >|∈D,i=2,…,n}

存储结构:

(1)表结点

typedef struct ArcNode

{

int adjvex;

struct ArcNode *nextarc;

}ArcNode;

(2)链表的存储结构

typedef struct VNode

{

int data;

ArcNode *firstarc;

}VNode,AdjList[MAX_VEXTEX_NUM];

(3)图的存储结构

typedef struct

{

AdjList vertices;

int vexnum, arcnum;

}ALGraph;

(4)栈的存储结构

typedef struct

{

ElemType *base;

ElemType *top;

int stacksize;

}SqStack;

三.程序设计

根据算法设计中给出的有关数据和算法,选定物理结构,详细设计需求分析中所要求的程序。包括:人机界面设计、主要功能的函数设计、函数之间调用关系描述等。

1界面设计

1)欢迎界面

数据结构拓扑排序实验报告与代码

2)输入顶点与边的关系,并得到拓扑排序

数据结构拓扑排序实验报告与代码

2主要功能

1)初始化栈

void InitStack(SqStack *S)//初始化栈

{

S->base = (ElemType *) malloc(STACK_INIT_SIZE * sizeof (ElemType));

if (!S->base) {

printf("memory allocation failed, goodbye");

exit(1);

}

S->top = S->base;

S->stacksize = STACK_INIT_SIZE;

}

2)出栈操作

int Pop(SqStack *S, ElemType *e)//出栈操作

{

if (S->top == S->base) {

return ERROR;

}

*e = *--S->top;

return 0;

}

3)进栈操作

void Push(SqStack *S, ElemType e)//进栈操作

{

if (S->top - S->base >= S->stacksize) {

S->base = (ElemType *) realloc(S->base, (S->stacksize + STACKINCREMENT) * sizeof (ElemType));

if (!S->base) {

printf("memory allocation failed, goodbye");

exit(1);

}

S->top = S->base + S->stacksize;

S->stacksize += STACKINCREMENT;

}

*S->top++ = e;

}

4)判断栈是否为空

int StackEmpty(SqStack *S)//判断栈是否为空

{

if (S->top == S->base)

return OK;

else

return ERROR;

}

5)构建图与欢迎界面

void CreatGraph(ALGraph *G)//构建图

{

int m, n, i;

ArcNode *p;

printf("************************************************\n");

printf(" 欢迎使用拓扑排序\n");

printf(" 制作者:----\n");

printf("************************************************\n");

printf("请输入顶点数和边数:");

scanf("%d%d", &G->vexnum, &G->arcnum);

for (i = 1; i <= G->vexnum; i++) {

G->vertices[i].data = i;

G->vertices[i].firstarc = NULL;

}

for (i = 1; i <= G->arcnum; i++) //输入存在边的点集合

{

printf("\n请输入存在边的两个顶点的序号:");

scanf("%d%d", &n, &m);

while (n < 0 || n > G->vexnum || m < 0 || m > G->vexnum) {

printf("输入的顶点序号不正确 请重新输入:");

scanf("%d%d", &n, &m);

}

p = (ArcNode*) malloc(sizeof (ArcNode));

if (p == NULL) {

printf("memory allocation failed,goodbey");

exit(1);

}

p->adjvex = m;

p->nextarc = G->vertices[n].firstarc;

G->vertices[n].firstarc = p;

}

}

6)找入度为零的结点

void FindInDegree(ALGraph G, int indegree[])//找入度为零的节点

{

int i;

for (i = 1; i <= G.vexnum; i++) {

indegree[i] = 0;

}

for (i = 1; i <= G.vexnum; i++) {

while (G.vertices[i].firstarc) {

indegree[G.vertices[i].firstarc->adjvex]++;

G.vertices[i].firstarc = G.vertices[i].firstarc->nextarc;

}

}

}

7)进行拓扑排序

void TopologicalSort(ALGraph G) //进行拓扑排序

{

int indegree[M];

int i, k, n;

int count = 0;

ArcNode *p;

SqStack S;

FindInDegree(G, indegree);

InitStack(&S);

for (i = 1; i <= G.vexnum; i++) {

if (!indegree[i])

Push(&S, i);

}

printf("进行拓扑排序输出顺序为:\n"); //输出结果

while (!StackEmpty(&S)) {

Pop(&S, &n);

printf("%4d", G.vertices[n].data);

count++;

for (p = G.vertices[n].firstarc; p != NULL; p = p->nextarc) {

k = p->adjvex;

if (!(--indegree[k])) {

Push(&S, k);

}

}

}

printf("\n");

if (count < G.vexnum) {

printf("该有向图有回路");

} else {

printf("排序成功\n");

}

}

3函数调用

数据结构拓扑排序实验报告与代码

数据结构拓扑排序实验报告与代码

四.测试与分析

1、不知道怎么选择储存结构

2、在写代码的过程中,没有弄清使用指针与引用之后,结构体如何使用。当使用指针的时候要使用‘.’,当使用引用或数的时候,要使用‘->’。

3、出栈入栈的条件很混乱,不知道该怎么去使用栈。

经验与体会:这个程序,要求我们想的要尽量全面,要将所有情况考虑清楚,不仅有图的知识,还有对栈的灵活应用记。在程序的全面性与健壮性上,我做的还不够好。因为书上有代码,所以不是太难,在栈的那部分比较混乱,又复习了一遍,现在更好的掌握了栈的基本操作几项基本操作,也对拓扑序列有了更清楚的认识。

源程序:

#include<STDIO.H>

#include<STDLIB.H>

#define MAX_VEXTEX_NUM 20 //最大顶点个数#define M 20

#define STACK_INIT_SIZE 100

#define STACKINCREMENT 10

#define OK 1

#define M 20

#define ERROR 0

typedef int ElemType;

typedef struct ArcNode //定义表结点结构

{

int adjvex; //与vi相邻接的顶点编号

struct ArcNode *nextarc; //指向下一条弧(边)的指针

} ArcNode;

typedef struct VNode //定义表头结点结构

{

int data;

ArcNode *firstarc; //指向第一条弧(边)的指针

} VNode, AdjList[MAX_VEXTEX_NUM];

typedef struct //定义邻接表结构

{

AdjList vertices; //表头结点数组

int vexnum, arcnum; //顶点和弧(边)的个数

} ALGraph;

typedef struct //构件栈

{

ElemType *base;

ElemType *top;

int stacksize;

} SqStack;

void InitStack(SqStack *); //函数声明

int Pop(SqStack *, ElemType *);

void Push(SqStack *, ElemType);

int StackEmpty(SqStack *);

void CreatGraph(ALGraph *);

void FindInDegree(ALGraph, int *);

void TopologicalSort(ALGraph);

void InitStack(SqStack *S)//初始化栈

{

S->base = (ElemType *) malloc(STACK_INIT_SIZE * sizeof (ElemType));

if (!S->base) {

printf("memory allocation failed, goodbye");

exit(1);

}

S->top = S->base;

S->stacksize = STACK_INIT_SIZE;

}

int Pop(SqStack *S, ElemType *e)//出栈操作

{

if (S->top == S->base) {

return ERROR;

}

*e = *--S->top;

return 0;

}

void Push(SqStack *S, ElemType e)//进栈操作

{

if (S->top - S->base >= S->stacksize) {

S->base = (ElemType *) realloc(S->base, (S->stacksize + STACKINCREMENT) * sizeof (ElemType));

if (!S->base) {

printf("memory allocation failed, goodbye");

exit(1);

}

S->top = S->base + S->stacksize;

S->stacksize += STACKINCREMENT;

}

*S->top++ = e;

}

int StackEmpty(SqStack *S)//判断栈是否为空

{

if (S->top == S->base)

return OK;

else

return ERROR;

}

void CreatGraph(ALGraph *G)//构建图

{

int m, n, i;

ArcNode *p;

printf("************************************************\n");

printf(" 欢迎使用拓扑排序\n");

printf(" 制作者:---\n");

printf("************************************************\n");

printf("请输入顶点数和边数:");

scanf("%d%d", &G->vexnum, &G->arcnum);

for (i = 1; i <= G->vexnum; i++) {

G->vertices[i].data = i;

G->vertices[i].firstarc = NULL;

}

for (i = 1; i <= G->arcnum; i++) //输入存在边的点集合

{

printf("\n请输入存在边的两个顶点的序号:");

scanf("%d%d", &n, &m);

while (n < 0 || n > G->vexnum || m < 0 || m > G->vexnum) {

printf("输入的顶点序号不正确 请重新输入:");

scanf("%d%d", &n, &m);

}

p = (ArcNode*) malloc(sizeof (ArcNode));

if (p == NULL) {

printf("memory allocation failed,goodbey");

exit(1);

}

p->adjvex = m;

p->nextarc = G->vertices[n].firstarc;

G->vertices[n].firstarc = p;

}

}

void FindInDegree(ALGraph G, int indegree[])//找入度为零的节点

{

int i;

for (i = 1; i <= G.vexnum; i++) {

indegree[i] = 0;

}

for (i = 1; i <= G.vexnum; i++) {

while (G.vertices[i].firstarc) {

indegree[G.vertices[i].firstarc->adjvex]++;

G.vertices[i].firstarc = G.vertices[i].firstarc->nextarc;

}

}

}

void TopologicalSort(ALGraph G) //进行拓扑排序

{

int indegree[M];

int i, k, n;

int count = 0;

ArcNode *p;

SqStack S;

FindInDegree(G, indegree);

InitStack(&S);

for (i = 1; i <= G.vexnum; i++) {

if (!indegree[i])

Push(&S, i);

}

printf("进行拓扑排序输出顺序为:\n"); //输出结果

while (!StackEmpty(&S)) {

Pop(&S, &n);

printf("%4d", G.vertices[n].data);

count++;

for (p = G.vertices[n].firstarc; p != NULL; p = p->nextarc) {

k = p->adjvex;

if (!(--indegree[k])) {

Push(&S, k);

}

}

}

printf("\n");

if (count < G.vexnum) {

printf("该有向图有回路");

} else {

printf("排序成功\n");

}

}

int main(void) //主函数

{

ALGraph G;

CreatGraph(&G);

TopologicalSort(G);

system("pause");

return 0;

}

更多相关推荐:
拓扑排序实验报告

实验题目图的应用实验目的1熟练掌握图的基本存储方法2熟练掌握图的深度优先和广度优先搜索方法3掌握AOV网和拓扑排序算法4掌握AOE网和关键路径实验内容拓扑排序任意给定一个有向图设计一个算法对它进行拓扑排序拓扑排...

数据结构实验报告4拓扑排序

01510800班郭哲学号20xx0259实验报告01510800班郭哲学号20xx0259101510800班郭哲学号20xx0259实验名称拓扑排序实验原理利用拓扑排序的原理读入图并将图按照拓扑排序的顺序输...

数据结构拓扑排序实验报告

拓扑排序基本要求用邻接表建立一个有向图的存储结构利用拓扑排序算法输出该图的拓扑排序序列编程思路首先图的创建采用邻接表建立逆向插入到单链表中特别注意有向是不需要对称插入结点且要把输入的字符在顶点数组中定位Loca...

实验十 图的拓扑排序问题

浙江大学城市学院实验报告课程名称数据结构与算法实验项目名称实验十图的拓扑排序问题学生姓名专业班级学号实验成绩指导老师签名日期一实验目的和要求1掌握拓扑排序概念2理解并能实现拓扑排序算法采用邻接表表示图二实验内容...

数据结构内排序实验报告

一实验目的1了解内排序都是在内存中进行的2为了提高数据的查找速度需要对数据进行排序3掌握内排序的方法二实验内容1设计一个程序exp101cpp实现直接插入排序算法并输出9876543210的排序过程1源程序如下...

拓扑排序课程设计报告

软件技术课程设计拓扑排序一目的通过课程设计加深对程序设计语言和软件技术基础课程所学知识的理解熟练掌握和巩固C语言的基本知识和语法规范包括数据类型整形实型字符型指针数组结构等运算类型算术运算逻辑运算自增自减运算赋...

实验10 图的拓扑排序问题,蓝礼巍

浙江大学城市学院实验报告课程名称数据结构与算法实验项目名称实验十图的拓扑排序问题学生姓名蓝礼巍专业班级学号实验成绩指导老师签名日期一实验目的和要求1掌握拓扑排序概念2理解并能实现拓扑排序算法采用邻接表表示图二实...

内部排序实验报告

深圳大学实验报告课程名称学院报告人实验时间实验报告提交时间教务部制深圳大学学生实验报告用纸2教师批改学生实验报告时间应在学生提交实验报告时间后10日内

实验报告_排序与查找

电子科技大学信息与软件工程学院实验报告电子科技大学实验报告课程名称学生姓名学号点名序号指导教师实验地点实验时间20xx20xx2学期信息与软件工程学院第1页电子科技大学信息与软件工程学院实验报告实验报告二学生姓...

排序算法实验报告

实验课程算法分析与设计实验名称几种排序算法的平均性能比较验证型实验实验目标1几种排序算法在平均情况下哪一个更快2加深对时间复杂度概念的理解实验任务1实现几种排序算法selectionsortinsertions...

查找与排序实验报告

实验四查找与排序实验目的1掌握顺序查找算法的实现2掌握折半查找算法的实现实验内容1编写顺序查找程序对以下数据查找37所在的位置5131921375664758088922编写折半查找程序对以下数据查找37所在的...

排序算法比较实验报告

天津职业技术师范大学数据结构课程设计1课程设计名称排序算法的比较概述排序是计算机程序设计中的一种重要操作它的功能是将一个数据元素或记录的任意序列重新排列成一个按关键字有序的序列内部排序算法主要分为5大类有十二个...

拓扑排序实验报告(9篇)