前言:今天终于把本周的所有任务AK了。
白天因为课满而且全是主课,所以没什么时间摸鱼,物理课也是划重点,所以没有敲代码。
晚上六点五十开始学习,继续把剩下的5个链表题做完了。
第一题:1523: 链表插入(线性表)
时间限制:1s
内存限制:128MB
题目描述
(线性表)已知一单链表,从第二个结点至表尾递增有序,(设a1<x<an)如下图(“第二个结点至表尾”指a1..an )。试编写程序,将第一个结点删除并插入表中适当位置,使整个链表递增有序。
输入格式
输入长度n:7
输入数据:4 1 2 3 6 8 9
输出格式
1 2 3 4 6 8 9
样例输入content_copy
5
11 7 8 9 10
样例输出content_copy
7 8 9 10 11
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define New (struct node*)malloc(sizeof(struct node))
typedef struct node
{
int data;
node *next;
} node;
int n,m;
node *creat(int num)//创建不带头结点的链表
{
node* head=NULL;
node* p1=head;
node* p2=NULL;
int data;
for(int i=0; i<num; i++)
{
scanf("%d",&data);
if(head==NULL)
{
head=New;
p1=head;
head->data=data;
}
else
{
p2=New;
p1->next=p2;
p2->data=data;
p1=p2;
p1->next=NULL;
}
}
return head;
}
int main()
{
int n;
node *head,*p1,*p2,*p3;
scanf("%d",&n);
p3=p2=head=creat(n);
head=p1=head->next;
int data=p2->data;
if(p1->data>data)//开插
head=p2;
else
while(p1)
{
if(p1->data>data)
break;
p2=p1;
p1=p1->next;
}
p2->next=p3;p3->next=p1;
while(head)
{
printf("%d ",head->data);
head=head->next;
}
}
第二题:1529: 链表查找(线性表)
时间限制:1s
内存限制:128MB
题目描述
已知非空线性链表由list指出,链结点的构造为(data,link).请写一算法,将链表中数据域值最小的那个链结点移到链表的最前面。要求:不得额外申请新的链结点
输入格式
输入长度n:6
输入数据:4 2 6 88 34 6
输出格式
2 4 6 88 34 6
样例输入content_copy
5
11 6 8 7 9
样例输出content_copy
6 11 8 7 9
结题思路:emm,非常简单,就是想找到然后放到第一个。、
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define New (struct node*)malloc(sizeof(struct node))
typedef struct node
{
int data;
node *next;
} node;
int n,m;
node *creat(int num)
{
node* head=NULL;
node* p1=head;
node* p2=NULL;
int data;
for(int i=0; i<num; i++)
{
scanf("%d",&data);
if(head==NULL)
{
head=New;
p1=head;
head->data=data;
}
else
{
p2=New;
p1->next=p2;
p2->data=data;
p1=p2;
p1->next=NULL;
}
}
return head;
}
node *minlist(node *head)
{
node *minnode=head,*p=head->next;
while(p)//找到最小的链表
{
if(minnode->data>p->data)
minnode=p;
p=p->next;
}
return minnode;
}
node *exchange(node *minn,node *head)
{
node *p=head;
while(p->next!=minn);
p->next=p->next->next;//找到最小的链表的位置后将他从链表删去
minn->next=head;
return minn;
}
void print(node *head)//输出链表
{
while(head)
{
printf("%d ",head->data);
head=head->next;
}
}
int main()
{
int n;
scanf("%d",&n);
node *head,*p,*minnode;
head=creat(n);
minnode=minlist(head);
head=exchange(minnode,head);
print(head);
}
第三题:1381: 双向链表
1s
128MB
题目描述
输入格式
输入:
第一行输入元素个数M
第二行输入M个元素
第三行输入删除位置,位置为0时不删除
第四行输入插入位置和插入元素
第五行输入输出时的起始位置
输出格式
样例输入content_copy
8
1 2 3 4 5 6 7 8
6
6 6
5
样例输出content_copy
5 6 7 8 1 2 3 4
解题思路:不知道为什么要用双向链表,感觉单项就足够了,建立一个双向循环链表,操作链表时注意走位~。
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define New (struct node*)malloc(sizeof(struct node))
struct node
{
int data;
node *next,*last;
};
int t;
node *creat(int n)
{
node *head=NULL,*p1,*p2;
int data;
for(int i=0; i<n; i++)
{
scanf("%d",&data);
if(head==NULL)
{
head=New;
head->data=data;
head->last=NULL;
head->next=NULL;
p1=head;
}
else
{
p2=New;
p2->data=data;
p1->next=p2;
p2->last=p1;
p2->next=head;
p1=p2;
}
}
head->last=p1;
return head;
}
node *dele(node *head,int n)
{
node *p=head,*p1=p;
for(int i=0; i<n-1; i++)
{
p1=p;
p=p->next;
}
if(p==NULL)
{
p1->next=head;
return head;
}
p1->next=p->next;
node *p2=p1->next;
p2->last=p1;
free(p);
return head;
}
node *addlist(node *head,int m,int n)
{
if(m==t)
{
node *p=New,*p1=head;
for(int i=0; i<m-2; i++)
p1=p1->next;
p->data=n;
p->next=head;
p->last=p1;
p1->next=p;
return head;
}
node *p=head,*p1=p;
for(int i=0; i<m-1; i++)
{
p1=p;
p=p->next;
}
node *p2=New;
p2->data=n;
p1->next=p2;
p2->last=p1;
p2->next=p;
p->last=p2;
return head;
}
void print(node *head,int m,int sum)//输出链表
{
int n=0;
node *p=head;
for(int i=0; i<m-1; i++)
p=p->next;
while(n<sum)
{
printf("%d ",p->data);
p=p->next;
n++;
}
}
int main()
{
int m,n;
scanf("%d",&t);
node *head=creat(t);
scanf("%d",&m);
if(m!=0)
head=dele(head,m);
else t++;
scanf("%d%d",&m,&n);
head=addlist(head,m,n);
scanf("%d",&m);
print(head,m,t);
}
第四题:1514: 合并链表(线性表)
时间限制:1s
内存限制:128MB
题目描述
(线性表)假设有两个按元素值递增次序排列的线性表,均以单链表形式存储。请编写算法将这两个单链表归并为一个按元素值递减次序排列的单链表,并要求利用原来两个单链表的结点存放归并后的单链表。
输入格式
输入长度n:5
输入数据:1 2 5 6 8
输入长度m:5
输入数据:3 4 7 9 10
输出格式
10 9 8 7 6 5 4 3 2 1
样例输入content_copy
4
7 9 10 11
4
8 12 13 14
样例输出content_copy
14 13 12 11 10 9 8 7
解题思路:将两个链表链接成一个链表,然后降序排列。
#include<bits/stdc++.h>
using namespace std;
#define New (struct node*)malloc(sizeof(struct node))
typedef struct node
{
int data;
node *next;
} node;
int n,m;
node *creat(int num)
{
node* head=NULL;
node* p1=head;
node* p2=NULL;
int data;
for(int i=0; i<num; i++)
{
scanf("%d",&data);
if(head==NULL)
{
head=New;
p1=head;
head->data=data;
}
else
{
p2=New;
p1->next=p2;
p2->data=data;
p1=p2;
p1->next=NULL;
}
}
return head;
}
node *sortlist(node *h)
{
node *h1,*p,*q,*qm,*pm,*t;
h1=NULL;
while(h)
{
for(pm=q=h,p=h->next;p;q=p,p=p->next)//每次找出链表中的最小值,qm记下最小值的前一个,pm记下最小值
if(p->data<pm->data)
{
qm=q;
pm=p;
}
if(pm!=h)//若最小值不是第一个,就将最小值的节点从链表中分离出来
qm->next=pm->next;
else
h=h->next;
pm->next=h1;//每次找出来的最大值用头插法实现升序
h1=pm;//h1始终指向升序链表的第一个节点
}
return h1;
}
void print(node *head)//输出链表
{
while(head)
{
printf("%d ",head->data);
head=head->next;
}
}
int main()
{
int m;
scanf("%d",&m);
node *heada,*headb,*pa;
pa=heada=creat(m);
scanf("%d",&m);
headb=creat(m);
while(pa->next)pa=pa->next;
pa->next=headb;
heada=sortlist(heada);
print(heada);
}
第五题:2395: 链表遍历(JSU-ZJJ)
时间限制:3s
内存限制:64MB
题目描述
小T昨天很不爽
昨天路过体彩销售点买了2注生日号码玩,当晚开奖后……
小T号码: 8902088
中奖号码:3902888
一个号码不对就差了十几万……
小T想:为什么规则是那样玩的啊……为什么5个号码要连续才能中二等奖啊……
我自己创建个规则,开N个数字,只要数字位置对了不一定要连续就可以有奖。
现在有一个中奖号码,有一个兑奖号码,小T想知道一共有多少个数字位置正确的,N太大了……
要求用链表做
输入格式
输入数据第一行包含一个整数T表示有T组测试数据
对于每组测试数据
第一行包含一个整数N,表示有N个数字
第二行包含N个中奖号码
第三行包含N个兑奖号码
输出格式
对于每组测试数据输出有多少个号码位置正确了
样例输入content_copy
2
7
3902888
8902088
10
1234567890
0987654321
样例输出content_copy
5
0
解题思路:将中奖号码和兑奖号码分别输入进两个结构体,一个一个比较计数就好。
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define New (struct node*)malloc(sizeof(struct node))
typedef struct node
{
char data;
node *next;
} node;
int n,m;
node *creat(int num)
{
node* head=NULL;
node* p1=head;
node* p2=NULL;
char data;
for(int i=0; i<num; i++)
{
scanf("%c",&data);
if(head==NULL)
{
head=New;
p1=head;
head->data=data;
}
else
{
p2=New;
p1->next=p2;
p2->data=data;
p1=p2;
p1->next=NULL;
}
}
return head;
}
int cnt(node* heada,node *headb)
{ int sum=0;
while(heada)
{
if(heada->data==headb->data)
sum++;
heada=heada->next;
headb=headb->next;
}
return sum;
}
int main()
{
int t;scanf("%d",&t);
getchar();
while(t--)
{
int sum=0,n;scanf("%d",&n);
node *heada=creat(n);
getchar();
node *headb=creat(n);
sum=cnt(heada,headb);
printf("%d\n",sum);
}
}
非常高兴今天能AK本周任务,可以专心备考了^^