一,学生信息
题目描述
现在想将学生绩点组成一个链表。链表结点内容包括学生姓名,学号,绩点
输入是一组学生的姓名、学号和绩点,以链表形式存储。
删除绩点小于平均绩点的学生结点,成为一个新链表。
后按照输入的顺序,依序输出新链表的学生信息。
平均绩点是输入的所有学生绩点取算术平均值。
输入描述
输入包括若干行。 每行是一个学生的姓名、学号和绩点,以空格隔开。
最后一行是*.
输出描述
输出包括学生姓名。 每个学生姓名一行。
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#define LEN sizeof(struct Student)
struct Student
{
char name[20];
int num;
float gpa;//绩点英文单词的缩写(grade point average)
struct Student *next;
};
void main()
{
struct Student *head,*p1,*p2;
int n=0,i=0;
float sum=0,average=0;
p1=p2=(struct Student *)malloc(LEN);
scanf("%s%d%f",&p1->name,&p1->num,&p1->gpa);
//scanf(%s%d%f)中间没有必要用空格。用空格表示你指定的输入格式;不用空格计算机会默认空格。
head=NULL;
for( ; ;)//表示不需要做任何判断,循环体中已有break
{
n=n+1;
sum=sum+p1->gpa;
if(n==1)head=p1;
else p2->next=p1;
p2=p1;
p1=(struct Student *)malloc(LEN);
scanf("%s",&p1->name);
if(strcmp(p1->name,"*")==0)break;
//以星号为结尾输出
else
scanf("%d%f",&p1->num,&p1->gpa);
}
p2->next=NULL;
average=sum/n;
p1=p2=head;
for( ;p1!=NULL; )
{
if(p1->gpa>average)
{
p2=p1;
p1=p1->next;
}
//判断头结点是否满足条件(上面),若不满足的话要改变头指针的方向;链表中间部分不满足条件时要如何删除;当结点满足条件时要如何移动指针。
else if(p1->gpa<average&&p1==head)
{
head=p1->next;
free(p1);//释放内存
p1=p2=head;
}
else if(p1->gpa<average&&p1!=head)
{
p2->next=p1->next;
free(p1);
p1=p2->next;
}
}
p1=head;
do
{
printf("%s\n",p1->name);
p1=p1->next;
}while(p1!=NULL);
}
二,单向链表
题目描述
struct Node{ int data; struct Node *next; }
编程实现:输入一个正整数 n (0<n<10),做 n 次下列运算: 输入若干个正整数(输入-1为结束标志),建立一个单向链表,将其中的奇数值结点删除后输出,若删除后链表为空则输出NULL。
输入描述
第一行一个正整数n表示有n组数据;
接下来n行,每一行输入若干个整数以-1位结束标志(-1不属于序列)
输出描述
输出删除奇数值结点后的链表
#include<stdio.h>
#include<malloc.h>
#define LEN sizeof(struct Node)
struct Node
{
int data;
struct Node *next;
};
int number=0;
void main()
{
void creat(int n);
int n;
scanf("%d",&n);
creat(n);
}
void creat(int n)
{
void del(struct Node *head);
void print(struct Node *head);
struct Node *head,*p1,*p2;
int i=0;
for(i=0;i<n;i++)
{
head=NULL;
p1=p2=(struct Node *)malloc(LEN);
scanf("%d",&p1->data);
for( ;p1->data!=-1; )
{
number++;
if(number==1)head=p1;
else
{
p2->next=p1;
p2=p1;
}
p1=(struct Node *)malloc(LEN);
scanf("%d",&p1->data);
}
p2->next=NULL;
del(head);
number=0;
}
}
void del(struct Node *head)
{
void print(struct Node *head);
struct Node *p1,*p2;
p1=p2=head;
for( ;p1!=NULL; )
{
if(p1->data%2!=0&&p1==head)
{
head=p1->next;
free(p1);
p1=p2=head;
}
else if(p1->data%2!=0&&p1!=head)
{
p2->next=p1->next;
free(p1);
p1=p2->next;
}
else if(p1->data%2==0)
{
p2=p1;
p1=p1->next;
}
}
print(head);
}
void print(struct Node *head)
{
struct Node *p=head;
if(p==NULL)printf("NULL");
else
for( ;p!=NULL; )
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
三,链表的交集
题目描述
已知两个非降序链表序列S1与S2,设计函数构造出S1与S2的交集新链表S3。
输入描述
输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。
输出描述
在一行中输出两个输入序列的交集序列,数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL
#include<stdio.h>
#include<stdlib.h>
struct list
{
int data;
struct list *next;
};
void print(struct list *head)
{
struct list *p=head;
if(!head)
{
printf("NULL");
return;
}
printf("%d",p->data);
for(p=p->next;p!=NULL;p=p->next)
printf(" %d",p->data);
}//打印结果
struct list *creat()
{
int i;//i为一组中的数据
struct list *head=NULL,*p,*q;
scanf("%d",&i);
if(i==-1)
return head;
head=(struct list *)malloc(sizeof(struct list));
head->data=i;
head->next=NULL;
p=head;
scanf("%d",&i);//输入每个数
for( ;i!=-1;scanf("%d",&i))
{
q=(struct list *)malloc(sizeof(struct list));
//第二组数据
q->data=i;
q->next=NULL;
p->next=q;
p=p->next;
}
return head;
}
struct list *jiaoji(struct list *list1,struct list *list2)
{
int a;
struct list *head=NULL,*p=list1,*q=list2,*s;
if(!list1||!list2)
return head;
for( ;p&&q; )
{
for( ;p&&q; )
{
if(p->data==q->data)
break;
else if(p->data>q->data)
q=q->next;
else
p=p->next;
}
if(!p||!q)break;
if(head==NULL)
{
head=(struct list *)malloc(sizeof(struct list));
head->data=p->data;
head->next=NULL;
s=head;
}
else
{
struct list *temp=(struct list *)malloc(sizeof(struct list));
temp->data=p->data;
temp->next=NULL;
s->next=temp;
s=s->next;
temp=NULL;
}
a=p->data;
p=p->next;
q=q->next;
}
return head;
}
void main()
{
struct list *list1,*list2;
list1=creat();
list2=creat();
print(jiaoji(list1,list2));
}
四,算法2-8~2-11:链表的基本操作
题目描述
链表是数据结构中一种最基本的数据结构,它是用链式存储结构实现的线性表。它较顺序表而言在插入和删除时不必移动其后的元素。现在给你一些整数,然后会频繁地插入和删除其中的某些元素,会在其中某些时候让你查找某个元素或者输出当前链表中所有的元素。
下面给你基本的算法描述:
图1:链表类型的定义以及获得链表元素的算法描述
图2:链表的插入算法描述
图3:链表的删除算法描述
图4:链表的创建算法描述
输入描述
输入数据只有一组,第一行有n+1个整数,第一个整数是这行余下的整数数目n,后面是n个整数。这一行整数是用来初始化列表的,并且输入的顺序与列表中的顺序相反,也就是说如果列表中是1、2、3那么输入的顺序是3、2、1。
第二行有一个整数m,代表下面还有m行。每行有一个字符串,字符串是“get”,“insert”,“delete”,“show”中的一种。如果是“get”或者“delete”,则其后跟着一个整数a,代表获得或者删除第a个元素;如果是“insert”,则其后跟着两个整数a和e,代表在第a个位置前面插入e;“show”之后没有整数。
输出描述
如果获取成功,则输出该元素;如果删除成功则输出“delete OK”;如果获取失败或者删除失败,则输出“get fail”以及“delete fail”。如果插入成功则输出“insert OK”,否则输出“insert fail”。如果是“show”则输出列表中的所有元素,如果列表是空的,则输出“Link list is empty”。注:所有的双引号均不输出。
提示:
1、因为输入数据中含有大量的插入和删除操作(不管你信不信,反正我信了),所以必须使用链表,否则很可能会超时。这也是考查链表的特性吧。
2、初始化链表的元素是倒序的,这个使用题目中创建列表的方法(从头部插入)就可以了。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define LEN sizeof(struct link)
struct link{
int data;
struct link * next;
};
struct match{
char a[20];
int data1;
int data2;
}item;
int main()
{
struct link * creat(int num);
void show(struct link * head);
struct link * del(struct link * head,int n);
struct link * insert(struct link * head,int n,int data3);
void get(struct link * head,int n);
struct link * head;
int num,m,i; //num为初始数据个数。
scanf("%d",&num);
head=creat(num);
scanf("%d",&m);
for(i=1;i<=m;i++)
{
scanf("%s",item.a);
if(strcmp(item.a,"show")==0)
show(head);
else if(strcmp(item.a,"delete")==0)
{
scanf("%d",&item.data1);
head=del(head,item.data1);
}
else if(strcmp(item.a,"insert")==0)
{
scanf("%d%d",&item.data1,&item.data2);
head=insert(head,item.data1,item.data2);
}
else if(strcmp(item.a,"get")==0)
{
scanf("%d",&item.data1);
get(head,item.data1);
}
}
return 0;
}
struct link * creat(int num)
{
struct link * head, * p;
int i;
head=NULL;
for(i=0;i<num;i++)
{
p=(struct link *)malloc(LEN);
scanf("%d",&p->data);
p->next=head;
head=p;
}
return head;
}
void show(struct link * head)
{
struct link * p1=head;
if(p1==NULL)
printf("Link list is empty\n");
else
{
for(;p1!=NULL;)
{
printf("%d ",p1->data);
p1=p1->next;
}
printf("\n");
}
}
struct link * del(struct link * head,int n)
{
struct link * p1, * p2;
int i;
int sign=0;
p1=p2=head;
for(i=1;p1!=NULL;i++)
{
if(i==n&&n==1)
{
sign=1;
head=p1->next;
free(p1);
p1=p2=head;
break;
}
else if(i==n&&n!=1)
{
sign=1;
p2->next=p1->next;
free(p1);
p1=p2->next;
break;
}
p2=p1;
p1=p1->next;
}
if(sign)
printf("delete OK\n");
else
printf("delete fail\n");
return head;
}
struct link * insert(struct link * head,int n,int data3)
{
int sign=0,i;
struct link * p1, * p2;
p1=p2=head;
if(p1==NULL&&n==1)
{
sign=1;
p1=(struct link *)malloc(LEN);
p1->data=data3;
head=p1;
p1->next=NULL;
}
else
{
for(i=1;p1!=NULL;i++)
{
if(i==n&&n==1)
{
sign=1;
p1=(struct link *)malloc(LEN);
p1->data=data3;
head=p1;
p1->next=p2;
p2=p1;
break;
}
else if(i==n-1&&n!=1)
{
sign=1;
p1=(struct link *)malloc(LEN);
p1->data=data3;
p1->next=p2->next;
p2->next=p1;
p2=p1;
break;
}
p1=p2=p1->next;
}
}
if(sign)
printf("insert OK\n");
else
printf("insert fail\n");
return head;
}
void get(struct link * head,int n)
{
int i,sign=0;
struct link * p1;
p1=head;
for(i=1;p1!=NULL;i++)
{
if(i==n)
{
sign=1;
printf("%d\n",p1->data);
}
p1=p1->next;
}
}