TPS_AOV_2 Algorithm made by Knuth {照TAOCP 2.2.3 完成}

这篇博客介绍了作者根据TAOCP 2.2.3部分实现的TPS_AOV_2算法,详细阐述了算法的输入、输出格式,并提供了测试案例。文章提到了拓扑排序的概念,建议使用邻接表来优化空间复杂度,并提醒读者动态内存分配和指针在算法中扮演重要角色。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我最近写了几篇TAOCP阅读笔记,大家可以去看看
其实我已近把全书很大一部分(除1.2,1.5,2.3,4,5节,及很多Execrise没写完)
好吧开始今天的写作。
(专有名词之前讲过了 大家可以去我之前的文章)了解

Question(TPS.cpp)

Input(TPS.qus)

第一行是一个数 NodeC,表示节点数
后面?行是两个数j,k,表示j在k前输出(1<j,k<=NodeC)
最后一行是两个0

Output(cout)

第1行:
一串从1到n的数字(无空格),并且对于在输入第2~n行出现的所有j,k,j在k前输出

若无满足的序列,则此行输出“Input Error”

第二行(这行是系统输出)

第一行若是Input Error,返回码为1
不然为0(听不懂?死一边去,就是出了错exit(1)不然return 0;)

Test

IN:
9
9 2
3 7
7 5
5 8
8 6
4 6
1 3
7 4
9 5
2 8
0 0

OUT:
193274586
System Exit With Code 0

第二个例子:

IN:
1
1 1
0 0

OUT:
Input Error
System Exit With Code 1

好了,这次我再讲讲思路
大家可以自己买TAOCP哈。

思考一下,拓扑排序无非就是寻找入度为0的那些Node,既然这样我们就应当把这些入度存下来。
为了方便找到值为0的NODE,我们可以把它存在一个Queue/Stack里
每找到一个无入度的NODE,我们需要遍历它所有的出度一遍,为了节省空间复杂度,同时方便遍历出度,我们可以用邻接表替代邻接矩阵。

对了,动态内存分配和指针这次会大量出现,请坐稳扶好。

code:

#include<iostream>
#include<fstream>
#include<queue>
#include<cstring>
#include<cstdlib>
#define ML 1000
using namespace std;

struct Node{
	Node* next;
	int v;
};

ifstream fin("TPS.qus");
Node* nds=NULL;//自动分配装逼(内存泄漏,深感不安)
queue<int> zs;
queue<int> LR;

int cnt=0;
int un_print=0;

int main(){
	//"Tobological sort"
	//T1
		//输入
		fin>>cnt;
		un_print=cnt;

		//calloc了解一下
		//auto allocate mem
		nds=(Node*)calloc(cnt+1,sizeof(Node));//直接访问1~n,免得减一

		for(int i=1;i<=cnt;++i){
			//calloc 自动将值设为0
			nds[i].next=NULL;
		}

		int j=0;
		int k=0;
		Node* temp=NULL;

		while(true){
			//T2
				fin>>j>>k;
				if(j==0)break;
			
			//T3
				++(nds[k].v);
			
				temp=(Node*)malloc(sizeof(Node));
				temp->v=k;
				temp->next=nds[j].next;
			
				nds[j].next=temp;
		}
		
		//T4
		for(i=1;i<=cnt;++i){
			if(nds[i].v==0){zs.push(i);}
		}
		while(!zs.empty()){
			//T5
			LR.push(zs.front());
			--un_print;
			temp=nds[zs.front()].next;

			//T6
			while(temp!=NULL){
				if((--nds[temp->v].v)==0){
					zs.push(temp->v);
				}

				Node* t2=temp;
				temp=temp->next;
				free((void*)t2);
			}
			zs.pop();
		}
		if(un_print!=0){
			cout<<"Input Error"<<endl;
			exit(1);
		}
		while(!LR.empty()){
			cout<<LR.front();
			LR.pop();
		}
		cout<<endl;
		free(nds);
		return 0;
}

好啦,下次继续

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值