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

时间:2024.4.7

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

一.需求分析

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插入排序直接插入排序的基本操作是将一个记录到已排好序的有序表中从而得到一个新的记录增...

数据结构排序实验报告

数据结构课程设计报告实验五排序一需求分析本演示程序用C60编写完成各种排序的实现对输入的一组数字实现不同的排序方法对其由小到大顺序输出1分别对直接插入排序希尔排序冒泡排序快速排序选择排序堆排序算法进行编写2对存...

数据结构排序算法实验报告

《数据结构》课程设计报告

数据结构实验报告——排序

1实验要求实验目的学习实现对比各种排序算法掌握各种排序算法的优劣以及各种算法使用的情况实验内容使用简单数组实现下面各种排序算法并进行比较排序算法1插入排序2希尔排序3冒泡排序4快速排序5简单选择排序6堆排序选作...

数据结构实验8排序

实验八排序一实验目的1熟悉掌握教材中所介绍的几种排序方法2学会分析各种内排序算法的性能二实验内容1随机产生20位整数2输入序列编写程序按下列排序方法将序列从小到大排序并输出1冒泡排序2快速排序3纪录每种方法比较...

数据结构快速排序实验报告

一问题描述在操作系统中我们总是希望以最短的时间处理完所有的任务但事情总是要一件件地做任务也要操作系统一件件地处理当操作系统处理一件任务时其他待处理的任务就需要等待虽然所有任务的处理时间不能降低但我们可以安排它们...

数据结构 内排序实验报告

通达学院实验报告20xx20xx学年第2学期课程名称数据结构实验名称基本内排序算法的验证和性能比较专业软件工程学生姓名班级学号10003102指导教师陈蕾日期20xx年5月29日南京邮电大学通达学院

排序实验数据结构

福州大学数计学院数据结构上机实验报告intpivotkeyLelemlow枢轴记录关键字whilelowlthigh从表的两端交替地向中间扫描whilelowlthighampampLelemhighgtpiv...

北邮数据结构实验报告实验四排序含源码

北京邮电大学信息与通信工程学院数据结构实验报告实验名称实验4排序学生姓名申宇飞班级20xx211103班内序号03学号20xx210064日期20xx年12月18日1实验要求使用简单数组实现下面各种排序算法并进...

数据结构 查找、排序的应用实验

淮海工学院计算机科学系实验报告书课程名数据结构题目查找排序的应用实验班级学号姓名数据结构实验报告1排序查找的应用实验报告要求1目的与要求1查找排序是日常数据处理过程中经常要进行的操作和运算掌握其算法与应用对于提...

数据结构_排序_实验报告 北邮

20xx级数据结构实验报告实验名称实验四排序学生姓名班级班内序号学号日期20xx年12月15日一实验要求1实验目的通过选择下面两个题目之一学习实现对比各种排序算法掌握各种排序算法的优劣以及各种算法使用的情况2实...

数据结构 实验报告 排序

实验报告实验目的1掌握各种排序方法的排序过程2了解一些排序算法的实现实验内容学生的考试成绩表由学生的学号姓名和成绩组成设计一个程序对给定的n个学生信1按分数高低排序打印出每个学生在考试中的排名分数相同的为同一名...

数据结构排序实验报告(34篇)