文章目录
2-1 Add Two Polynomials (20分)
Write a function to add two polynomials. Do not destroy the input.
Use a linked list implementation with a dummy head node.使用一个带有虚拟头结点的链表实现
Note: The zero polynomial is represented by an empty list with only the dummy head node.零多项式有一个只有虚拟头结点的空列表实现
Format of functions:
Polynomial Add( Polynomial a, Polynomial b );
where Polynomial
is defined as the following:
typedef struct Node *PtrToNode;
struct Node {
int Coefficient;
int Exponent;
PtrToNode Next;
};
typedef PtrToNode Polynomial;
/* Nodes are sorted in decreasing order of exponents.结点按指数的递减顺序排序*/
The function Add
is supposed to return a polynomial which is the sum of a
and b
.
Sample program of judge:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node *PtrToNode;
struct Node {
int Coefficient;
int Exponent;
PtrToNode Next;
};
typedef PtrToNode Polynomial;
Polynomial Read(); /* details omitted */
void Print( Polynomial p ); /* details omitted */
Polynomial Add( Polynomial a, Polynomial b );
int main()
{
Polynomial a, b, s;
a = Read();
b = Read();
s = Add(a, b);
Print(s);
return 0;
}
/* Your function will be put here */
Sample Input:
4
3 4 -5 2 6 1 -2 0
3
5 20 -7 4 3 1
Sample Output:
5 20 -4 4 -5 2 9 1 -2 0
代码如下:
尾插法的应用
Polynomial Add( Polynomial a, Polynomial b ){
Polynomial t1=a,t2=b,head,rear,tmp;
head = (Polynomial)malloc(sizeof(struct Node));head->Next = NULL;
rear = head;
while(t1&&t2){
if(t1->Exponent==t2->Exponent){
if(t1->Coefficient+t2->Coefficient){
Polynomial P = (Polynomial)malloc(sizeof(struct Node));
P->Coefficient = t1->Coefficient+t2->Coefficient;P->Exponent=t1->Exponent;
rear->Next = P;rear = P; //尾插法
}
t1=t1->Next;t2=t2->Next;
}else if(t1->Exponent<t2->Exponent){
Polynomial P = (Polynomial)malloc(sizeof(struct Node));
P->Coefficient = t2->Coefficient;P->Exponent=t2->Exponent;
rear->Next = P;rear = P; //尾插法
t2=t2->Next;
}else{
Polynomial P = (Polynomial)malloc(sizeof(Polynomial));
P->Coefficient = t1->Coefficient;P->Exponent=t1->Exponent;
rear->Next = P;rear = P; //尾插法
t1=t1->Next;
}
}
rear->Next=t1?t1:t2; //相当于写循环把t1/t2剩下的结点一个个加到链表中
return head; //根据题意,空结点不用释放
}
2-2 学生成绩链表处理 (20分)
本题要求实现两个函数,一个将输入的学生成绩组织成单向链表;另一个将成绩低于某分数线的学生结点从链表中删除。
函数接口定义:
struct stud_node *createlist();
struct stud_node *deletelist( struct stud_node *head, int min_score );
函数createlist
利用scanf
从输入中获取学生的信息,将其组织成单向链表,并返回链表头指针。
链表节点结构定义如下:
struct stud_node {
int num; /*学号*/
char name[20]; /*姓名*/
int score; /*成绩*/
struct stud_node *next; /*指向下个结点的指针*/
};
输入为若干个学生的信息(学号、姓名、成绩),当输入学号为0时结束。
函数deletelist
从以head
为头指针的链表中删除成绩低于min_score
的学生,并返回结果链表的头指针。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
struct stud_node {
int num;
char name[20];
int score;
struct stud_node *next;
};
struct stud_node *createlist();
struct stud_node *deletelist( struct stud_node *head, int min_score );
int main()
{
int min_score;
struct stud_node *p, *head = NULL;
head = createlist();
scanf("%d", &min_score);
head = deletelist(head, min_score);
for ( p = head; p != NULL; p = p->next )
printf("%d %s %d\n", p->num, p->name, p->score);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
1 zhang 78
2 wang 80
3 li 75
4 zhao 85
0
80
输出样例:
2 wang 80
4 zhao 85
代码如下:
链表的建立和删除操作
核心:尾插法 和 删除当前节点需要知道当前结点的前一个结点的位置
struct stud_node *createlist(){
struct stud_node *h,*r,*tmp,*P;
h = (struct stud_node *)malloc(sizeof(struct stud_node));
r = h;
int num,score;char sname[20];
scanf("%d",&num);
while(num){
scanf("%s %d",sname,&score);
P = (struct stud_node *)malloc(sizeof(struct stud_node));P->next=NULL;
P->num = num;P->score=score;
strcpy(P->name,sname); //P->name=sname;
r->next = P;r = P;
scanf("%d",&num);
}
tmp = h;h=h->next;free(tmp); //由主函数里的输出语句可知返回的指针不带空头结点
return h; //有的博客没有上一行删除空结点的操作直接返回h->next,此法虽简单但是内存会有一个没使用的空间
}
struct stud_node *deletelist( struct stud_node *head, int min_score ){
struct stud_node *p1,*p2;
p1=p2=head;
while(head!=NULL&&head->score<min_score){
head=head->next;
p1=p2=head;
}
while(p2!=NULL){
p2=p2->next; //当前p2是刚从上一个while循环里出来的score>=min_score,所以让p2指向自己下一个
if(p2==NULL) return head;
else if(p2->score<min_score){
p1->next=p2->next;
p2=p1;
}else p1=p1->next; //p1始终是p2的前一个结点,删除操作必须要知道当前结点的前一个结点的位置
}
return head;
}
2-3 链表拼接 (20分)
本题要求实现一个合并两个有序链表的简单函数。
链表结点定义如下:
struct ListNode {
int data;
struct ListNode *next;
};
函数接口定义:
struct ListNode *mergelists(struct ListNode *list1, struct ListNode *list2);
其中list1
和list2
是用户传入的两个按data
升序链接的链表的头指针;函数mergelists
将两个链表合并成一个按data
升序链接的链表,并返回结果链表的头指针。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
struct ListNode {
int data;
struct ListNode *next;
};
struct ListNode *createlist(); /*裁判实现,细节不表*/
struct ListNode *mergelists(struct ListNode *list1, struct ListNode *list2);
void printlist( struct ListNode *head )
{
struct ListNode *p = head;
while (p) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
int main()
{
struct ListNode *list1, *list2;
list1 = createlist();
list2 = createlist();
list1 = mergelists(list1, list2);
printlist(list1);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
1 3 5 7 -1
2 4 6 -1
输出样例:
1 2 3 4 5 6 7
代码如下:
struct ListNode *mergelists(struct ListNode *list1, struct ListNode *list2){
if(!list1&&!list2) return NULL;
int flag=0;
struct ListNode *h = NULL,*r,*P;
r = h;
while(list1&&list2){
P = (struct ListNode *)malloc(sizeof(struct ListNode));P->next = NULL;
P->data = list1->data<list2->data ? list1->data : list2->data;
if(!flag){
h = P;
r = h;
flag=1;
}else{
r->next = P;
r = P;
}
if(list1->data<list2->data) list1=list1->next;
else list2=list2->next;
}
r->next=list1?list1:list2;
return h;
}
2-4 另类堆栈 (20分)
在栈的顺序存储实现中,另有一种方法是将Top定义为栈顶的上一个位置。请编写程序实现这种定义下堆栈的入栈、出栈操作。如何判断堆栈为空或者满?
函数接口定义:
bool Push( Stack S, ElementType X );
ElementType Pop( Stack S );
其中Stack结构定义如下:
typedef int Position;
typedef struct SNode *PtrToSNode;
struct SNode {
ElementType *Data; /* 存储元素的数组 */
Position Top; /* 栈顶指针 */
int MaxSize; /* 堆栈最大容量 */
};
typedef PtrToSNode Stack;
注意:如果堆栈已满,Push
函数必须输出“Stack Full
”并且返回false
;如果堆栈是空的,则Pop
函数必须输出“Stack Empty
”,并且返回ERROR
。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
#define ERROR -1
typedef int ElementType;
typedef enum { push, pop, end } Operation;
typedef enum { false, true } bool;
typedef int Position;
typedef struct SNode *PtrToSNode;
struct SNode {
ElementType *Data; /* 存储元素的数组 */
Position Top; /* 栈顶指针 */
int MaxSize; /* 堆栈最大容量 */
};
typedef PtrToSNode Stack;
Stack CreateStack( int MaxSize )
{
Stack S = (Stack)malloc(sizeof(struct SNode));
S->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
S->Top = 0;
S->MaxSize = MaxSize;
return S;
}
bool Push( Stack S, ElementType X );
ElementType Pop( Stack S );
Operation GetOp(); /* 裁判实现,细节不表 */
void PrintStack( Stack S ); /* 裁判实现,细节不表 */
int main()
{
ElementType X;
Stack S;
int N, done = 0;
scanf("%d", &N);
S = CreateStack(N);
while ( !done ) {
switch( GetOp() ) {
case push:
scanf("%d", &X);
Push(S, X);
break;
case pop:
X = Pop(S);
if ( X!=ERROR ) printf("%d is out\n", X);
break;
case end:
PrintStack(S);
done = 1;
break;
}
}
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
4
Pop
Push 5
Push 4
Push 3
Pop
Pop
Push 2
Push 1
Push 0
Push 10
End
输出样例:
Stack Empty
3 is out
4 is out
Stack Full
0 1 2 5
代码如下:
bool Push( Stack S, ElementType X ){
if(S->Top==S->MaxSize){
printf("Stack Full\n");
return false;
}
S->Data[S->Top++] = X; //S->Top是当前元素上一个位置正好为空直接装入然后S->Top指向再上一个
return true;
}
ElementType Pop( Stack S ){
if(S->Top==0){
printf("Stack Empty\n");
return ERROR;
}
return S->Data[--S->Top];
}
2-5 Two Stacks In One Array (20分)
Write routines to implement two stacks using only one array. Your stack routines should not declare an overflow unless every slot in the array is used. 除非使用数组的每一个空间否则堆栈不应声明溢出
Format of functions:
Stack CreateStack( int MaxElements );
int IsEmpty( Stack S, int Stacknum );
int IsFull( Stack S );
int Push( ElementType X, Stack S, int Stacknum );
ElementType Top_Pop( Stack S, int Stacknum );
where int Stacknum
is the index of a stack which is either 1 or 2; int MaxElements
is the size of the stack array; and Stack
is defined as the following:
typedef struct StackRecord *Stack;
struct StackRecord {
int Capacity; /* maximum size of the stack array */
int Top1; /* top pointer for Stack 1 */
int Top2; /* top pointer for Stack 2 */
ElementType *Array; /* space for the two stacks */
}
Note: Push
is supposed to return 1 if the operation can be done successfully, or 0 if fails. If the stack is empty, Top_Pop
must return ERROR which is defined by the judge program.
Sample program of judge:
#include <stdio.h>
#include <stdlib.h>
#define ERROR 1e8
typedef int ElementType;
typedef enum { push, pop, end } Operation;
typedef struct StackRecord *Stack;
struct StackRecord {
int Capacity; /* maximum size of the stack array */
int Top1; /* top pointer for Stack 1 */
int Top2; /* top pointer for Stack 2 */
ElementType *Array; /* space for the two stacks */
};
Stack CreateStack( int MaxElements );
int IsEmpty( Stack S, int Stacknum );
int IsFull( Stack S );
int Push( ElementType X, Stack S, int Stacknum );
ElementType Top_Pop( Stack S, int Stacknum );
Operation GetOp(); /* details omitted */
void PrintStack( Stack S, int Stacknum ); /* details omitted */
int main()
{
int N, Sn, X;
Stack S;
int done = 0;
scanf("%d", &N);
S = CreateStack(N);
while ( !done ) {
switch( GetOp() ) {
case push:
scanf("%d %d", &Sn, &X);
if (!Push(X, S, Sn)) printf("Stack %d is Full!\n", Sn);
break;
case pop:
scanf("%d", &Sn);
X = Top_Pop(S, Sn);
if ( X==ERROR ) printf("Stack %d is Empty!\n", Sn);
break;
case end:
PrintStack(S, 1);
PrintStack(S, 2);
done = 1;
break;
}
}
return 0;
}
/* Your function will be put here */
Sample Input:
5
Push 1 1
Pop 2
Push 2 11
Push 1 2
Push 2 12
Pop 1
Push 2 13
Push 2 14
Push 1 3
Pop 2
End
Sample Output:
Stack 2 is Empty!
Stack 1 is Full!
Pop from Stack 1: 1
Pop from Stack 2: 13 12 11
代码如下:
Stack CreateStack( int MaxElements ){
Stack S = (Stack)malloc(sizeof(struct StackRecord));
S->Array = (ElementType *)malloc(MaxElements*sizeof(ElementType));
S->Capacity = MaxElements;
S->Top1 = -1;
S->Top2 = MaxElements;
return S;
}
int IsEmpty( Stack S, int Stacknum ){
if(Stacknum==1&&S->Top1==-1) return 1;
else if(Stacknum==2&&S->Top2==S->Capacity) return 1;
return 0;
}
int IsFull( Stack S ){
return S->Top2-S->Top1==1?1:0;
}
int Push( ElementType X, Stack S, int Stacknum ){
if(IsFull(S)) return 0;
if(Stacknum==1) S->Array[++(S->Top1)]=X;
else S->Array[--(S->Top2)]=X;
return 1;
}
ElementType Top_Pop( Stack S, int Stacknum ){
if(IsEmpty(S,Stacknum)) return ERROR;
if(Stacknum==1) return S->Array[(S->Top1)--];
else return S->Array[(S->Top2)++];
}