拓扑排序:
因为上一篇有点小问题(Stack.base == Stack.top 写成了 Stack.base == Stack.base)导致死循环,最后导致内存溢出,地址访问冲突
参考上一篇的链接:
https://blog.csdn.net/qq_43552933/article/details/119745683
更正后的代码如下:
1.栈代码:
#pragma once
#include<stdio.h>
#define maxSize 100
typedef struct stack {int * base;int * top;
}stack;
bool init(stack & Stack) {//栈的初始化Stack.base = new int[maxSize];if (!Stack.base) {return false;}Stack.top = Stack.base;return true;
}
bool push(stack & Stack,int e) {//入栈if (Stack.top - Stack.base == maxSize) {//满栈,不能再插入return false;}*(Stack.top) = e;Stack.top++;return true;
}
bool pop(stack & Stack, int &e) {//出栈if (Stack.base == Stack.top) {//栈空return false;}Stack.top--;e = *(Stack.top);return true;
}
int getTop(stack &Stack) {if (Stack.base == Stack.top) {//栈空return -1;}return *(Stack.top - 1);
}
void printStack(stack Stack) {//遍历栈中的元素while (Stack.base != Stack.top) {printf("%d ", *(Stack.top - 1));Stack.top--;}
}
bool empty(stack Stack) {//栈空的判断if (Stack.base == Stack.top) {return true;}return false;
}
void testStack() {//测试栈是否有问题stack Stack;init(Stack);int value;while (1) {scanf_s("%d", &value);if (value == -1) {break;}push(Stack, value);}printStack(Stack);
}
2.拓扑排序代码:
#include<stdio.h>
#include<stdlib.h>
#include "stack.h"
#define typeNode int //每个头结点的标识数据类型
#define N 100 //最大结点数
int degree[N];
int result[N];
typedef struct dNode {//每个头结点后紧跟的单位结点int data;struct dNode * next;
}dNode;
typedef struct mNode {//邻接表中每一行的头结点typeNode data;dNode * first;//指向第一个有效的后继结点
}mNode;
typedef struct {mNode vNode[N];//所有头结点int vNum, eNum;//图中顶点的数量和边数量
}zNode;
void init(zNode &ZNode) {printf("规定顶点从0开始取\n");scanf_s("%d%d", &ZNode.vNum, &ZNode.eNum);//输入有向图的顶点数和边数for (int i = 0; i < ZNode.vNum; i++) {//规定顶点从0开始取scanf_s("%d", &ZNode.vNode[i].data);ZNode.vNode[i].first = NULL;}for (int i = 0; i < ZNode.eNum; i++) {int u, v;scanf_s("%d%d", &u, &v);//u顶点到v顶点有边dNode* p = new dNode();p->data = v;p->next = ZNode.vNode[u].first;//只有指针域,指向地址ZNode.vNode[u].first= p;}
}
void print(zNode ZNode) { printf("遍历链表:\n");for (int i = 0; i < ZNode.vNum; i++) {dNode* temp = ZNode.vNode[i].first;printf("%d ->", ZNode.vNode[i].data);while(temp){printf("%d ->",temp->data);temp = temp->next;}printf("NULL\n");}
}
void calculate(zNode ZNodeReverse) {//返回有向图每个顶点的入度//每个顶点的入度for (int i = 0; i < ZNodeReverse.vNum; i++) {int tempLength = 0;dNode* p = new dNode();p = ZNodeReverse.vNode[i].first;while (p) {tempLength ++;p = p->next;}degree[i] = tempLength;}
}
bool tuoPuSort(zNode ZNode,int result[],stack &Stack) {//拓扑排序只是找到学习的先后依赖顺序,并不是排序int count = 0;//计数for (int i = 0; i < ZNode.vNum; i++) {if (!degree[i]) {//对入度为0的点入栈push(Stack, i);}}while (!empty(Stack)) {dNode* p ;int tempV = getTop(Stack);result[count] = tempV;count++;int e=0;pop(Stack, e);p = ZNode.vNode[tempV].first;//取以tempV顶点为入度点while (p) {//和tempV相连的邻接边的入度减1int v = p->data;degree[v]--;if (!degree[v]) {push(Stack, v);}p = p->next;}}if (count < ZNode.vNum) {return false;}else {return true;}
}
int main() {zNode ZNode,ZNodeReverse;printf("邻接表的构造:\n");init(ZNode);print(ZNode);printf("逆邻接表的构造:\n");init(ZNodeReverse);print(ZNodeReverse);calculate(ZNodeReverse);stack Stack;init(Stack);printf("拓扑序列如下: ");if (tuoPuSort(ZNode, result,Stack)) {printf("\n可以构成拓扑序列!");};for (int i = 0; i < ZNode.vNum; i++) {printf("%d ", result[i]);}printf("\n");system("pause");return 0;
}