【无标题】

#include <stdio.h>
#include <stdlib.h>
#include <string.h>



//   邻接表
typedef struct node {
	int adjvex;		//邻接点域
node* Next;		//指向下一个邻边节点的指针域
}edgeNode;//邻接表结点


//顶点表结点
typedef struct {		
	char Date[10];		//课程编号        
	int Credit;		//节点学分(每门课学分)

	char name[10];//课程名字 
	
	edgeNode* edgenext;		//指向邻接表第一个邻边节点的指针域
	int InDegree;		//课程入度
}vertexnode;


//每学期的学期信息
typedef struct  {		
	int classnumber;		//学期数
	int termnum;		//每学期学分上限  题目为要求8 
}Message;

//图
typedef struct  {		
	vertexnode* Vertics;		//邻接表域
	int VexNum;		//节点数 题目要求有11门课程  
	int ArcNum;		//边数
	Message* infor;		//学期与课程信息
}Graph;

int Locate(char* ch) {		//将C1C2C3……等变为1 2 3...
	return (2 == strlen(ch)) ? ch[1] - '1' : (ch[1] - '0') * 10 + ch[2] - '1';
}


void search(Graph *G) {		//从文件读取课程信息
	

	FILE* fp = fopen("D123.txt", "r");
	if (NULL == fp) {
		printf("文件路径有误!!!");
		exit(1);
	}
	
	
	G->Vertics = (vertexnode*)malloc(sizeof(vertexnode) * G->VexNum);
	for (int i = 0; i < G->VexNum; i++)
		G->Vertics[i].edgenext = NULL;		//初始化
		
	for (int i = 0; i < 11; i++) {		//读取课程信息,循环11次 
	

		fscanf(fp, "%s%s%d", G->Vertics[i].Date,G->Vertics[i].name, &G->Vertics[i].Credit);		//读取课程名称和学分



	
		while ('\n' != fgetc(fp)) {		//根据先修课程建立邻接表结点
			char str[4];
			int s;
			fscanf(fp, "%s", str);
			s = Locate(str);
			if (s < 0 || s > G->VexNum) {		//判断课程是否有错误
				printf("%s输入错误!\n", G->Vertics[i].Date);
				exit(1);
			}
			edgeNode* p = (edgeNode*)malloc(sizeof(edgeNode));		//更新邻接表结点
			p->adjvex = i;
			p->Next = G->Vertics[s].edgenext; 
			G->Vertics[s].edgenext = p;
			G->ArcNum++;
		}
	}
		printf("请输入查询课程名称:\n");
//查询课程信息 
	char name[10];
	scanf("%s",&name);

		 if(strcmp(G->Vertics[0].name,name)==0)
		 
		 	printf("%s %d\n",G->Vertics[0].Date,G->Vertics[0].Credit); 
		  
		else  if(strcmp(G->Vertics[1].name,name)==0)
		 
		 	printf("%s %d\n",G->Vertics[1].Date,G->Vertics[1].Credit); 
		  
		else  if(strcmp(G->Vertics[2].name,name)==0)
		 
		 	printf("%s %d\n",G->Vertics[2].Date,G->Vertics[2].Credit); 
		  
		else if(strcmp(G->Vertics[3].name,name)==0)
		 
		 	printf("%s %d\n",G->Vertics[3].Date,G->Vertics[3].Credit); 
		 
		else if(strcmp(G->Vertics[4].name,name)==0)
		 
		 	printf("%s %d\n",G->Vertics[4].Date,G->Vertics[4].Credit); 
		  
		else if(strcmp(G->Vertics[5].name,name)==0)
		 
		 	printf("%s %d\n",G->Vertics[5].Date,G->Vertics[5].Credit); 
		 
		else if(strcmp(G->Vertics[6].name,name)==0)
		 
		 	printf("%s %d\n",G->Vertics[6].Date,G->Vertics[6].Credit); 
		 
		else if(strcmp(G->Vertics[7].name,name)==0)
		 
		 	printf("%s %d\n",G->Vertics[7].Date,G->Vertics[7].Credit); 
		  
		else if(strcmp(G->Vertics[8].name,name)==0)
		 
		 	printf("%s %d\n",G->Vertics[8].Date,G->Vertics[8].Credit); 
		  
		
		else if(strcmp(G->Vertics[9].name,name)==0)
		
		 	printf("%s %d\n",G->Vertics[9].Date,G->Vertics[9].Credit); 
		  
		
		else if(strcmp(G->Vertics[10].name,name)==0)
		 
		 	printf("%s %d\n",G->Vertics[10].Date,G->Vertics[10].Credit); 
		   
		else{
			printf("输入的课程名称不对"); 
			exit(1); 
		};
		
		
	fclose(fp);
	
	
	for (int i = 0; i < G->VexNum; i++)		//更新入度
		G->Vertics[i].InDegree=0;
	for (int i = 0; i < G->VexNum; i++) {
		for (edgeNode* p = G->Vertics[i].edgenext; NULL != p; p = p->Next) {
			G->Vertics[p->adjvex].InDegree++;
		}

	}
}

void input(Graph* G) {		//输入学期 6或7 
	G->infor = (Message*)malloc(sizeof(Message));		//初始化指针
	printf("请输入需要排课学期总数(输入6或7)  \n");
	scanf("%d", &G->infor->classnumber);
	G->infor->termnum=8;//题目要求每学期学分为8 
    G->VexNum=11;//题目要求共有11个课程 
}




//拓扑排序算法 
void Top(vertexnode g[], int n,vertexnode *temp)		//用有入度域的aov网进行拓扑排序,输出并存到数组temp中
{
	
	int i, j, k, top, m = 0;
	edgeNode* p;
	top = -1;		//链栈初始化,-1为栈尾
	for(i = 0; i < n; i ++)			//将入度为0的顶点链接成链栈
		if (g[i].InDegree == 0)
		{
			g[i].InDegree = top;
			top = i;
		}

	

	
	while (top != -1)		//当链栈非空时
	{
		j = top;		//将栈顶顶点记为j
		top = g[top].InDegree;		//栈顶指针指向弹出栈后下一个入度为0的顶点

		temp[m] = g[j];		//将顶点信息有序保存到数组
		m++;		//记录已输出的顶点个数
		p = g[j].edgenext;
		while (p != NULL)		//删除顶点j的所有出边
		{
			k = p->adjvex;
			g[k].InDegree--;		//将顶点j的邻接边节点k入度减1
			if (g[k].InDegree == 0)		//若顶点k入度为零则入链栈
			{
				g[k].InDegree = top;
				top = k;
			}
			p = p->Next;		//查找下一个邻接边节点
		}
	}
	if (m < n)
		printf("有错误");
}



void Sort1(vertexnode* t, Message* s, int VexNum)		//按各学期负担均匀输出并保存教学计划
{
	FILE* fp = fopen("D123.txt", "r");
	int c = 0;		//用于输出课程信息
	for (int i = 0; i < s->classnumber; i++)
	{
		int b = 0;		//累计每学期学分
		printf("\n第%d个学期的课程为:", i + 1);

		for (int j = 0; j < VexNum / s->classnumber; j++)
		{
			if (b + t[c].Credit <= s->termnum)		//判断是否超过最大学分
			{
				if (c == VexNum)break;
				printf("%s  ", t[c].Date);		//输出课程
				fprintf(fp, "%s ", t[c].Date);
				b = b + t[c].Credit;		//学分累计
				c++;		//指向下一课程
			}
		}
		if (i < VexNum % s->classnumber)		//加入平均后多余的课程
		{
			if (c == VexNum)break;
			printf("%s  ", t[c].Date);		//输出课程
			fprintf(fp, "%s ", t[c].Date);
			b = b + t[c].Credit;		//学分累计
			c++;		//指向下一课程
		}
	}
}

int main() {
	Graph G;
    search(&G);		//从文件读取课程信息并查询 
    
	input(&G);//输入学期6或7 

    vertexnode s[99];		//拓扑排序
	Top(G.Vertics, G.VexNum, s);		//拓扑排序 

    Sort1(s, G.infor, G.VexNum); //排列算法 
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值