东北大学计算机专业研究生入学考试2006年真题

这是一个包含两道C语言编程题目的博客。第一题涉及编写递归函数,检查输入的n个单词是否按字典顺序排列。第二题涉及处理三个有序整数链表,删除A链表中同时存在于B和C链表的元素。

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

/*-------------------------------------------------------C语言部分------------------------------------------------------------------*/
/*三.由键盘输入n(n<50)个英文单词,每个单词由空格分隔。试编写一个递归函数,判断这n个单词是否是按字典顺序排列的。*/
#include<stdio.h>
#include<string.h>
#define MAXSIZE 50
int WordSort(char word[][15], int n)
{
	if (n < 0)
		return -1;
	else if (n == 1)
		return 1;
	else 
	{
		if(strcmp(word[n-1], word[n-2])>0 && WordSort(word, n-1))
			return 1;
		else 
			return 0;
	}
}
void main()
{
	char word[MAXSIZE][15];
	int size, i;
	
	printf("输入单词个数,小于50:\n");
	scanf("%d", &size);

	printf("\n输入%d单词,以空格隔开:\n", size);
	for (i = 0; i < size; i++)
		scanf("%s", word[i]);

	switch (WordSort(word, size))
	{
		case -1: 
			printf("\n请输入单词\n");break;
		case 0:
			printf("\n输入的单词不是按字典顺序排序!\n");break;
		case 1:
			printf("\n输入的单词是按字典顺序排序!\n");break;
		default: ;
	}
}

/*四.设有A,B,C三个有序的整数链表(同为递增),试编写程序,删去A链表中那些既在B链表中出现又在C链表中出现的结点。*/
#include <stdio.h>
#include <malloc.h>
typedef struct LNode
{
	int data;
	struct LNode *next;
}LNode;

int CreateLinkList(LNode **head) //创建链表
{
	int iCount, i, iElem;
	LNode *pTemp;
	
	//建立头结点
	*head = (LNode *)malloc(sizeof(LNode));
	(*head)->next = NULL;
	
	printf("\nPlease input the number of elements: ");
	scanf("%d", &iCount);
  if (!iCount)
		return 0;
		
	for (i = 0; i < iCount; i++)
	{
		printf("No.%d element: ", iCount-i);
		scanf("%d", &iElem);
		pTemp = (LNode *)malloc(sizeof(LNode));
		pTemp->data = iElem;
		pTemp->next = (*head)->next;
		(*head)->next = pTemp;
	}
	return 1;
}

int SortLinkList(LNode *head)  //链表排序
{
	LNode *pFront, *pSearch;
	int iElem;
	if (!head->next)
	{
		printf("Empty!\n");
		return 0;
	}
	pFront = head->next;
	if (pFront->next)
		pSearch = pFront->next;
	while (pSearch)
	{
		if (pFront->data > pSearch->data)
		{
			iElem = pFront->data;
			pFront->data = pSearch->data;
			pSearch->data = iElem;
		}
		pSearch = pSearch->next;
		pFront = pFront->next;
	}
  return 1;
}

void DisplayLinkList(LNode *head)  //输出链表
{
	LNode *pTemp;
	pTemp = head->next;
	if (!pTemp)
		printf("Empty!");
	else
	{
		while (pTemp)
		{
			printf("%d->", pTemp->data);
	      pTemp = pTemp->next;
		}
	}
}

int DeleteLinkList(LNode *head) //删除链表
{
	LNode *pCurrent;
	if (!head->next)
	{
		printf("Empty!");
		return 0;
	}
	pCurrent = head->next;
	while (pCurrent)
	{
		head->next = pCurrent->next;
		free(pCurrent);
		pCurrent = head->next;
	}
	return 1;
}

void Delete(LNode *La, LNode *Lb, LNode *Lc)  //删除链表A中既存在B又存在C中的元素
{
	LNode *pa, *pb, *pc, *q;
	pa = La;
  pb = Lb->next;
  pc = Lc->next;
	while (pb && pc)   //思路:在链表B和C中查找相同的元素看看此元素是否在A链表中
	{
		if (pb->data < pc->data)
			pb = pb->next;
		else if (pc->data < pb->data)
			pc = pc->next;
		else   //找到lb和lc中都出现的结点
		{
			while (pa->next)
			{
				if (pa->next->data < pb->data)
					pa = pa->next;
				else if (pa->next->data > pb->data)
				{
					pa = pa->next;
					pb = pb->next;
					pc = pc->next;
					break;
				}
				else   //删除la中也包含的该元素
				{
					q = pa->next;
					pa->next = q->next;
					free(q);
					
					pa = pa->next;
					pb = pb->next;
					pc = pc->next;
					break;					
				}
			}
		}
	}
}

int main()
{
	LNode *La, *Lb, *Lc;
	
	//创建链表
	printf("\nCreate Linklist La:");  //a
	CreateLinkList(&La);
  printf("\nCreate Linklist Lb:");  //b
	CreateLinkList(&Lb);
  printf("\nCreate Linklist Lc:");  //c
	CreateLinkList(&Lc);

	//排序前输出链表
  printf("\nLinklist La is :");    //a
	DisplayLinkList(La);
	printf("\nLinklist Lb is :");    //b
	DisplayLinkList(Lb);
  printf("\nLinklist Lc is :");    //c
	DisplayLinkList(Lc);

	//链表排序
	SortLinkList(La);   //a
  SortLinkList(Lb);   //b
  SortLinkList(Lc);   //c

	//排序后输出链表
  printf("\nAfter Sorted, linklist La is:");  //a
  DisplayLinkList(La);
  printf("\nAfter Sorted, linklist Lb is:");  //b
  DisplayLinkList(Lb);
  printf("\nAfter Sorted, linklist Lc is:");  //c
  DisplayLinkList(Lc);

  Delete(La, Lb, Lc);  //删除链表A中既存在B又存在C中的元素

  printf("\nAfter Delete the same elements in Lb and Lc from La:\n");

  printf("\\nLinklist La is :");   //a
  DisplayLinkList(La);
  printf("\\nLinklist Lb is :");   //b
  DisplayLinkList(Lb);
  printf("\\nLinklist Lc is :");   //c
  DisplayLinkList(Lc);

  DeleteLinkList(La);
  DeleteLinkList(Lb);
  DeleteLinkList(Lc);
	return 0;
} 

/*五.试编写一个程序,从键盘上输入一个整数,在整数文件"a.dat"中查找,要求:
     1.若文件"a.dat"不存在,则建立一个新文件"a.dat",将该整数写入文件;
	 2.若文件中找到了这个整数,则显示数据存在,否则将该数据写入文件。*/
#include <stdio.h>
void main()
{
	FILE *fp1, *fp2;
	int num, numCur, flag = 0;
	printf("\nInput a integer: ");
	scanf("%d", &num);
	
	//说明:要区分读和写的概念!!读和写都是针对计算机而言的,read是指计算机读(input),等同于人将文件写入 ;write是指计算机output
	if ((fp1 = fopen("a.dat", "rb+"))==NULL && (fp2 = fopen("a.dat", "wb+")) != NULL)   
	{
		printf("No File! Create it and write the number into it!\n");
		fprintf(fp2, "%d", num);
		fclose(fp2);
	}
	else
	{
		printf("\nYes!Find the File!\n");
		while (!feof(fp1))
		{
			fscanf(fp1, "%d", &numCur);
			if (numCur == num)
			{
				printf("\nFind the number: %d\n", num);
				flag = 1;
			}
	}
	if (!flag)
	{
		printf("\nNo find the number: %d append it into the file!\n", num);
		fprintf(fp1, " %d", num);  //因为要将这个数字写到文件中(相当于计算机input),所以用的是fp1
		fclose(fp1);
	}
}

/*--------------------------------------------------------数据结构部分---------------------------------------------------------------*/
/*二.设单链表的表头指针为h,结点结构由data和next两个域构成,其中data域为字符型。编写算法,判断该链表的前n个字符组成的是否为回文,要求使用
栈和队列。(回文是指正读反读均相同的字符序列,如"abba"和"abdba"均是回文,但"good"不是回文。)
!!!!!!!!!!!!!!!!!!!!关于回文的题在2000中考过,不过2000的题中是要求用递归来做的,这道题是用单链表,栈,队列来做。
从这个角度想,我认为给我们提供了一个复习的思路,就是考过的知识点完全可能再考,只不过角度有一点变化,所以在复习真题时要触类旁通!
举个例子,比如树的遍历问题,用递归怎么做,不用递归又怎么做。*/

void main()
{
	SqStack S; //声明一个栈
	LinkQueue L; //声明一个队列
	
	InitStack(&S); //初始化栈
	InitQueue(&L);  //初始化队列
	
	char c[30];
	ElemType a,b;
	printf("请输入要判断的字符,以@结束(最多30个字符):");
	scanf("%s",c);
	int i = 0;
	int flag1 = 0;
	int flag2 = 0;
	while(c[i] != '@')
	{
		Push(&S,c[i]); //入栈
		EnQueue(&L,c[i]);
		flag1++;
		i++;
	}
	while(!(S.top == S.base))
	{
		Pop(&S,&b);  //出栈
		DeQueue(&L,&a);  //出队
		if(a == b)
		{
			flag2++;
		}
		else
		{
			break;
		}
	}
	if(flag1 == flag2)
		printf("\n是回文");
	else
		printf("\n不是回文");
}

/*三.设二叉树二叉链表为存储结构,编写计算二叉树tree中所有节点的平衡因子,同时返回二叉树tree中非叶结点个数的算法。*/
//!!!!!!!!!!!!!这道题是2002年第五大题的一部分,具体代码就不写了……

/*四.设G=(V,E)是一个以邻接表存储的无向无环图,编写一个给图G中每个顶点赋以一个整数序号的算法,并满足以下条件:
     若从顶点i到顶点j有一条弧,则应使i<j。(要求用最少的时间和辅助空间)*/
	 
/*[题目分析] 本题的含义是对有向无环图(DAG)的顶点,以整数适当编号后,可使其邻接矩阵中对角线以下元素全部为零。
根据这一要求,可以按各顶点出度大小排序,使出度最大的顶点编号为1,出度次大者编号为2,出度为零的顶点编号为n。
这样编号后,可能出现顶点编号i<j,但却有一条从顶点到j到i的弧。这时应进行调整,即检查每一条弧,若有<i,j>,且i>j,
则使顶点j的编号在顶点i的编号之前。*/

void Adjust(AdjMatrix g1 ,AdjMatrix g2)//对以邻接矩阵存储的DAG图g1重新编号,使若有<i,j>,则编号i<j,重新编号后的图以邻接矩阵g2存储。
{
	typedef struct
	{
		int vertex;  //顶点
		int out;    //出度
		int count;  //计数
	}node ; 
    node v[];   //顶点元素数组。
    int c[];    //中间变量
    for (i = 1;i <= n;i++)    //顶点信息数组初始化,设图有n个顶点。
    {
		v[i].vertex = i;
		v[i].out = 0;
		v[i].count = 1;//count=1为最小
		c[i] = 1;
	}   
	
    for (i = 1;i <= n;i++)    //计算每个顶点的出度。
        for (j = 1;j <= n;j++)
			v[i].out += g1[i][j]; 
			
    for (i = n;i >= 2;i--)    //对v的出度域进行计数排序,出度大者,count域中值小。
	{ 
        for (j = i-1;j >= 1;j--) 
		{
            if (v[i].count <= v[j].count) 
				v[i].count++;
			else v[j].count++;
		}
	}
	
    for (i = 1;i <= n;i++) //第二次调整编号。若<i,j>且i>j,则顶点j的编号在顶点i的编号之前
	{
        for (j = i;j <= n;j++)   
            if(g1[i][j] == 1 && v[i].count>v[j].count)
		    {
				v[i].count = v[j].count;
				v[j].count++;
			}
	}	   
		   
    for (i = n;i >= 2;i--)) //对v的计数域v[i].count排序,按count域从小到大顺序存到数组c中。
	{
        for (j = i-1;j >= 1;j--) 
		{		
            if (v[i].count < v[j].count)
				c[j]++;
			else c[i]++;
		}
	}	   
    
	for (i = 1;i <= n;i++)
		v[i].count = c[i]; //将最终编号存入count 域中。
		
    for (i = 1;i <= n;i++)
        for (j = 1;j <= n;j++) 
		{
           g2[v[i].count][v[j].count] = g1[v[i].vertex][v[j].vertex];
		}
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值