问题 A: 算法2-8~2-11:链表的基本操作
[命题人 : 外部导入]
时间限制 : 1.000 sec 内存限制 : 32 MB
题目描述
链表是数据结构中一种最基本的数据结构,它是用链式存储结构实现的线性表。它较顺序表而言在插入和删除时不必移动其后的元素。现在给你一些整数,然后会频繁地插入和删除其中的某些元素,会在其中某些时候让你查找某个元素或者输出当前链表中所有的元素。
下面给你基本的算法描述:
图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”。注:所有的双引号均不输出。
样例输入 Copy
3 3 2 1
21
show
delete 1
show
delete 2
show
delete 1
show
delete 2
insert 2 5
show
insert 1 5
show
insert 1 7
show
insert 2 5
show
insert 3 6
show
insert 1 8
show
get 2
样例输出 Copy
1 2 3
delete OK
2 3
delete OK
2
delete OK
Link list is empty
delete fail
insert fail
Link list is empty
insert OK
5
insert OK
7 5
insert OK
7 5 5
insert OK
7 5 6 5
insert OK
8 7 5 6 5
7
代码:
#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std;
typedef struct Node{
int data;
Node* next;
}Node,*Linklist;
void getNode(Linklist L){
int i=0,x;
scanf("%d",&x);
Node* s;
while(s&&i<x){
s=s->next;
i++;
}
if(s==NULL)
printf("get fail\n");
else
printf("%d\n",s->data);
}
void insertNode(Linklist &L){
int x;
scanf("%d",&x);
int j=0,y;
Node* r=L;
Node* s=(Node*)malloc(sizeof(Node));
scanf("%d",&y);
if(x==1){
printf("insert OK\n");
s->data=y;
s->next=r->next;
r->next=s;
}else{
while(r->next&&j<x-1){
r=r->next;
j++;
}
if(r->next==NULL){
printf("insert fail\n");
}else{
printf("insert OK\n");
s->data=y;
s->next=r->next;
r->next=s;
}
}
}
void deleteNode(Linklist &L){
int x;
scanf("%d",&x);
int i=0;
Node* s;
Node* r;
s=L;
while(s->next&&i<x-1){
s=s->next;
i++;
}
if(s->next==NULL)
printf("delete fail\n");
else{
printf("delete OK\n");
r=s->next;
s->next=s->next->next;
delete(r);
}
}
void showLinklist(Linklist L){
Node* k;
k=L;
if(k->next==NULL){
printf("Link list is empty\n");
}else{
while(k->next!=NULL){
k=k->next;
if(k->next!=NULL)
printf("%d ",k->data);
else
printf("%d\n",k->data);
}
}
}
int main(){
Linklist L;
int x;
scanf("%d",&x);
L=(Node*)malloc(sizeof(Node));
L->next=NULL;
Node* s;
int y;
for(int i=0;i<x;i++){
scanf("%d",&y);
s=(Node*)malloc(sizeof(Node));
s->data=y;
s->next=L->next;
L->next=s;
}
int z;
char p[10];
scanf("%d",&z);
for(int i=0;i<z;i++){
getchar();
scanf("%s",p);
if(strcmp(p,"show")==0){
showLinklist(L);
}else if(strcmp(p,"delete")==0){
deleteNode(L);
}else if(strcmp(p,"insert")==0){
insertNode(L);
}else{
getNode(L);
}
}
return 0;
}
给我整吐了,写了这么久,在电脑上的编译器通过了,可是在网上的编译器上就是通过不了,检查发现我的代码出现了致命错误!
在电脑上的的运行效果图:

可是:

最后发现自己的输出本不应该有空格的,其实不用空格,也可编译。
#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std;
typedef struct Node{
int data;
Node* next;
}Node,*Linklist;
void getNode(Linklist L){
int i=0,x;
scanf("%d",&x);
Node* s;
while(s&&i<x){
s=s->next;
i++;
}
if(s==NULL)
printf("get fail\n");
else
printf("%d\n",s->data);
}
int getLength(Linklist L){
Node* s;
s=L;
int length=0;
while(s->next){
s=s->next;
length++;
}
return length;
}
void insertNode(Linklist &L){
int length=getLength(L);
int x;
scanf("%d",&x);
int j=0,y;
Node* r=L;
Node* s=(Node*)malloc(sizeof(Node));
scanf("%d",&y);
if(x==length+1){
while(r&&j<x-1){
r=r->next;
j++;}
printf("insert OK\n");
s->data=y;
s->next=r->next;
r->next=s;
}else if(x==1){
printf("insert OK\n");
s->data=y;
s->next=r->next;
r->next=s;
}else{
while(r->next&&j<x-1){
r=r->next;
j++;
}
if(r->next==NULL){
printf("insert fail\n");
}else{
printf("insert OK\n");
s->data=y;
s->next=r->next;
r->next=s;
}
}
}
void deleteNode(Linklist &L){
int x;
scanf("%d",&x);
int i=0;
Node* s;
Node* r;
s=L;
while(s->next&&i<x-1){
s=s->next;
i++;
}
if(s->next==NULL)
printf("delete fail\n");
else{
printf("delete OK\n");
r=s->next;
s->next=s->next->next;
delete(r);
}
}
void showLinklist(Linklist &L){
Node* k;
k=L;
if(k->next==NULL){
printf("Link list is empty\n");
}else{
while(k->next!=NULL){
k=k->next;
if(k->next!=NULL)
printf("%d",k->data);
else
printf("%d\n",k->data);
}
}
}
int main(){
int x;
scanf("%d",&x);
Linklist L;
L=(Node*)malloc(sizeof(Node));
L->next=NULL;
Node* s;
int y;
for(int i=0;i<x;i++){
scanf("%d",&y);
s=(Node*)malloc(sizeof(Node));
s->data=y;
s->next=L->next;
L->next=s;
}
int z;
char p[10];
scanf("%d",&z);
for(int i=0;i<z;i++){
scanf("%s",p);
if(strcmp(p,"show")==0){
showLinklist(L);
}else if(strcmp(p,"delete")==0){
deleteNode(L);
}else if(strcmp(p,"insert")==0){
insertNode(L);
}else{
getNode(L);
}
}
return 0;
}
效果图:

最后依然扑GAI,不管了,可能细节出了问题。
最后找了网上可以AC的代码,对运行结果进行对比:

发现完全一样!
初步怀疑是第一个·的例子出现问题,也就是测试的例子并不是第一个。
问题 B: C语言-链表排序
[命题人 : 外部导入]
时间限制 : 1.000 sec 内存限制 : 128 MB
题目描述
已有a、b两个链表,每个链表中的结点包括学号、成绩。要求把两个链表合并,按学号升序排列。
输入
第一行,a、b两个链表元素的数量N、M,用空格隔开。 接下来N行是a的数据 然后M行是b的数据 每行数据由学号和成绩两部分组成
输出
按照学号升序排列的数据
样例输入 Copy
2 3
5 100
6 89
3 82
4 95
2 10
样例输出 Copy
2 10
3 82
4 95
5 100
6 89
代码:
#include<iostream>
using namespace std;
int Node[100000];
bool visit[100000];
int main(){
int x,y;
while(cin>>x>>y){
for(int i=0;i<x;i++){
int z,l;
cin>>z>>l;
Node[z]=l;
visit[z]=true;
}
for(int i=0;i<y;i++){
int f,k;
cin>>f>>k;
Node[f]=k;
visit[f]=true;
}
for(int i=0;i<100000;i++){
if(visit[i])
cout<<i<<" "<<Node[i]<<endl;
}
}
}
程序运行效果图:、

效果图:

当然也可以不用这样做,但是这样做简单:
换一种思路:
改用动态链表来做:
其效果都是一样的,只不过这样做是比较复杂:
动态链表的代码:
#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;
typedef struct Node{
int data;
int address;
Node* next;
}Node,*Linklist;
void foamSort(Linklist &L,int x){
Node* s;
int temp,mount;
for(int i=0;i<x-1;i++){
for(s=L;s->next!=NULL;s=s->next){
if(s->address>s->next->address){
temp=s->data;
s->data=s->next->data;
s->next->data=temp;
mount=s->address;
s->address=s->next->address;
s->next->address=mount;
}
}
}
}
int main(){
Linklist L;
L=(Node*)malloc(sizeof(Node));
Linklist M;
M=(Node*)malloc(sizeof(Node));
L->next=NULL;
M->next=NULL;
int x,y;
scanf("%d%d",&x,&y);
Node* s;
Node* t;
int u,v;
for(int i=0;i<x;i++){
scanf("%d%d",&u,&v);
s=(Node*)malloc(sizeof(Node));
s->data=v;
s->address=u;
s->next=L->next;
L->next=s;
}
foamSort(L,x);
for(int i=0;i<y;i++){
scanf("%d%d",&u,&v);
t=(Node*)malloc(sizeof(Node));
t->data=v;
t->address=u;
t->next=M->next;
M->next=t;
}
foamSort(M,y);
Linklist C;
C=(Node*)malloc(sizeof(Node));
C->next=NULL;
Node* h;
h=C=L;
Node* k;
k=M->next;
Node* l;
l=L->next;
while(l&&k){
if(l->data<k->data){
h->next=l;
h=l;
l=l->next;
}else{
h->next=k;
h=k;
k=k->next;
}
h->next=l?l:k;
}
Node* m;
for(m=C->next;m!=NULL;m=m->next)
printf("%d %d\n",m->address,m->data);
}
想了一会儿,最后成功写出来关于动态链表的实现的程序。总之一定要学会对头节点的初值进行初始化。
问题 C: 最快合并链表(线性表)
[命题人 : 外部导入]
时间限制 : 1.000 sec 内存限制 : 128 MB
题目描述
知L1、L2分别为两循环单链表的头结点指针,m,n分别为L1、L2表中数据结点个数。要求设计一算法,用最快速度将两表合并成一个带头结点的循环单链表。
输入
m=5
3 6 1 3 5
n=4.
7 10 8 4
输出
3 6 1 3 5 7 10 8 4
样例输入 Copy
7
3 5 1 3 4 6 0
5
5 4 8 9 5
样例输出 Copy
3 5 1 3 4 6 0 5 4 8 9 5
运用动态链表的代码实现:
#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;
typedef struct Node{
int data;
Node* next;
}Node,*Linklist;
int main(){
int a,b;
Linklist L;
L=(Node*)malloc(sizeof(Node));
Linklist M;
M=(Node*)malloc(sizeof(Node));
scanf("%d",&a);
Node* s,*u;
u=L;
int x;
for(int i=0;i<a;i++){
scanf("%d",&x);
s=(Node*)malloc(sizeof(Node));
s->data=x;
u->next=s;
u=s;
}
scanf("%d",&b);
Node *t,*h;
h=M;
int y;
for(int i=0;i<b;i++){
scanf("%d",&y);
t=(Node*)malloc(sizeof(Node));
t->data=y;
h->next=t;
h=t;
}
Node *j,*k,*p;
j=L->next;
k=M->next;
Linklist v;
p=v=L;
for(int i=0;i<a;i++){
p->next=j;
p=j;
j=j->next;
}
for(int i=0;i<b;i++){
p->next=k;
p=k;
k=k->next;
}
for(Node* z=v->next;z!=NULL;z=z->next){
if(z->next!=NULL)
printf("%d ",z->data);
else
printf("%d\n",z->data);
}
}
代码运行截图:

效果图:

运用静态链表进行程序的实现:
代码:
#include<iostream>
using namespace std;
int num[100000];
int main(){
int a,b;
cin>>a;
for(int i=0;i<a;i++){
cin>>num[i];
}
cin>>b;
for(int i=0;i<b;i++){
cin>>num[a+i];
}
for(int i=0;i<a+b;i++){
if(i!=a+b-1)
cout<<num[i]<<" ";
else
cout<<num[i]<<endl;
}
}
代码运行截图:

效果图:

问题 D: 链表查找(线性表)
[命题人 : 外部导入]
时间限制 : 1.000 sec 内存限制 : 128 MB
题目描述
线性表(a1,a2,a3,…,an)中元素递增有序且按顺序存储于计算机内。要求设计一算法完成:
(1) 用最少时间在表中查找数值为x的元素。
(2) 若找到将其与后继元素位置相交换。
(3) 若找不到将其插入表中并使表中元素仍递增有序。
输入
输入:x=3
输入长度:9
输入数据:2 3 5 7 12 15 17 23 45
输出
相同元素为:3
交换后的链表为:2 5 3 7 12 15 17 23 45
样例输入 Copy
4
9
2 3 5 7 12 15 17 23 45
样例输出 Copy
no
2 3 4 5 7 12 15 17 23 45
代码:
运用动态链表进行实现的程序的代码:
#include<iostream>
#include<cstdlib>
using namespace std;
typedef struct Node{
int data;
Node* next;
}Node,*Linklist;
bool getElem(Linklist L,int x){
bool flag=false;
for(Node* l=L;l!=NULL;l=l->next){
if(l->data==x)
flag=true;
}
return flag;
}
void InsertNode(Linklist &L,int x){
int i=0,j=0;
Node *s,*r;
r=(Node*)malloc(sizeof(Node));
s=L->next;
while(s&&x>s->data){
s=s->next;
j++;
}
s=L;
while(s&&i<j){
s=s->next;
i++;
}
r->data=x;
r->next=s->next;
s->next=r;
}
void showLinklist(Linklist L){
Node* d;
d=L;
while(d->next){
d=d->next;
if(d->next)
cout<<d->data<<" ";
else
cout<<d->data<<endl;
}
}
void changeposition(Linklist &L,int x){
Node* s;
s=L->next;
int i=1;
while(s&&x>s->data){
s=s->next;
i++;
}
s=L;
int j=0;
while(s->next&&j<i){
s=s->next;
j++;
}
int temp=s->next->data;
s->next->data=s->data;
s->data=temp;
}
int main(){
int a,b;
cin>>a>>b;
Linklist L;
L=(Node*)malloc(sizeof(Node));
Node *s,*r;
r=L;
int x;
for(int i=0;i<b;i++){
cin>>x;
s=(Node*)malloc(sizeof(Node));
s->data=x;
r->next=s;
r=s;
}
s->next=NULL;
if(getElem(L,a)){
cout<<"yes"<<endl;
changeposition(L,a);
showLinklist(L);
}else{
cout<<"no"<<endl;
InsertNode(L,a);
showLinklist(L);
}
}
结果图:

运用静态链表实现代码:
#include<iostream>
using namespace std;
int c[100000];
int main(){
int a,b;
cin>>a>>b;
for(int i=0;i<b;i++){
cin>>c[i];
}
bool flag=false;
for(int i=0;i<b;i++){
if(c[i]==a){
flag=true;
continue;
}
}
if(flag){
cout<<"yes"<<endl;
int sum=0;
for(int i=0;i<b;i++){
if(c[i]==a){
sum=i;
continue;
}
}
int temp=c[sum];
c[sum]=c[sum+1];
c[sum+1]=temp;
for(int i=0;i<b;i++){
if(i!=b-1)
cout<<c[i]<<" ";
else
cout<<c[i]<<endl;
}
}
else{
cout<<"no"<<endl;
int count=0;
for(int i=0;i<b;i++){
if(c[i]>a){
count=i;
break;
}
}
for(int t=b-1;t>=count;t--){
c[t+1]=c[t];
}
c[count]=a;
for(int i=0;i<b+1;i++){
if(i!=b)
cout<<c[i]<<" ";
else
cout<<c[i]<<endl;
}
}
}
效果图:

问题 E: 算法2-24 单链表反转
[命题人 : 外部导入]
时间限制 : 10.000 sec 内存限制 : 128 MB
题目描述
根据一个整数序列构造一个单链表,然后将其反转。
例如:原单链表为 2 3 4 5 ,反转之后为5 4 3 2
输入
输入包括多组测试数据,每组测试数据占一行,第一个为大于等于0的整数n,表示该单链表的长度,后面跟着n个整数,表示链表的每一个元素。整数之间用空格隔开
输出
针对每组测试数据,输出包括两行,分别是反转前和反转后的链表元素,用空格隔开
如果链表为空,则只输出一行,list is empty
样例输入 Copy
5 1 2 3 4 5
0
样例输出 Copy
1 2 3 4 5
5 4 3 2 1
list is empty
运用数组的顺序表的方法进行实现:
#include<iostream>
using namespace std;
int num[100000];
int main(){
int a;
while(cin>>a){
if(a==0){
cout<<"list is empty"<<endl;
continue;
}
else{
for(int i=0;i<a;i++){
cin>>num[i];
}
for(int i=0;i<a;i++){
if(i!=a-1)
cout<<num[i]<<" ";
else
cout<<num[i]<<endl;
}
for(int i=a-1;i>=0;i--){
if(i!=0)
cout<<num[i]<<" ";
else
cout<<num[i]<<endl;
}
}
}
}
效果图:

运用链表的方法进行实现:
#include<iostream>
#include<cstdlib>
using namespace std;
typedef struct Node{
int data;
Node* next;
}Node,*Linklist;
int main(){
int a;
while(~scanf("%d",&a)){
if(a==0){
printf("list is empty\n");
continue;
}
else{
Linklist L;
L=(Node*)malloc(sizeof(Node));
L->next=NULL;
Node* s;
int x;
for(int i=0;i<a;i++){
s=(Node*)malloc(sizeof(Node));
scanf("%d",&x);
s->data=x;
s->next=L->next;
L->next=s;
if(i!=a-1)
printf("%d ",s->data);
else
printf("%d\n",s->data);
}
for(Node* t=L->next;t!=NULL;t=t->next){
if(t->next)
printf("%d ",t->data);
else
printf("%d\n",t->data);
}
}
}
}
效果图:

中规中矩的单链表逆置的代码:
#include<iostream>
#include<cstdlib>
using namespace std;
typedef struct Node{
int data;
Node* next;
}Node,*Linklist;
int main(){
int a;
while(~scanf("%d",&a)){
if(a==0){
printf("list is empty\n");
continue;
}
else{
Linklist L;
L=(Node*)malloc(sizeof(Node));
Node* r;
r=L;
Node* s;
int x;
for(int i=0;i<a;i++){
s=(Node*)malloc(sizeof(Node));
scanf("%d",&x);
s->data=x;
r->next=s;
r=s;
if(i!=a-1)
printf("%d ",s->data);
else
printf("%d\n",s->data);
}
s->next=NULL;
Node* temp=L;
Node* prev=NULL;
while(temp){
temp=temp->next;
L->next=prev;
prev=L;
L=temp;
}
for(Node* t=prev;t->next!=NULL;t=t->next){
if(t->next->next)
printf("%d ",t->data);
else
printf("%d\n",t->data);
}
}
}
}
效果图:

问题 F: 算法2-25 有序单链表删除重复元素
[命题人 : 外部导入]
时间限制 : 30.000 sec 内存限制 : 128 MB
题目描述
根据一个递增的整数序列构造有序单链表,删除其中的重复元素
输入
输入包括多组测试数据,每组测试数据占一行,第一个为大于等于0的整数n,表示该单链表的长度,后面跟着n个整数,表示链表的每一个元素。整数之间用空格隔开
输出
针对每组测试数据,输出包括两行,分别是删除前和删除后的链表元素,用空格隔开
如果链表为空,则只输出一行,list is empty
样例输入 Copy
5 1 2 3 4 5
5 1 1 2 2 3
0
样例输出 Copy
1 2 3 4 5
1 2 3 4 5
1 1 2 2 3
1 2 3
list is empty
第一次做就做错了,但是不屈服!
五十分的代码:
#include<iostream>
#include<cstdlib>
using namespace std;
typedef struct Node{
int data;
Node* next;
}Node,*Linklist;
int main(){
int a;
while(~scanf("%d",&a)){
if(a==0){
printf("list is empty\n");
continue;
}
else{
Linklist L;
L=(Node*)malloc(sizeof(Node));
Node* r;
r=L;
Node* s;
int x;
for(int i=0;i<a;i++){
s=(Node*)malloc(sizeof(Node));
scanf("%d",&x);
s->data=x;
r->next=s;
r=s;
if(i!=a-1)
printf("%d ",s->data);
else
printf("%d\n",s->data);
}
s->next=NULL;
Node* p=(Node*)malloc(sizeof(Node));
Node* f=p;
Node* h;
for(Node* m=L->next;m->next!=NULL;m=m->next){
bool flag=true;
for(Node* j=L->next;j->next!=NULL;j=j->next){
if(m->data==j->data&&j->next->data==j->data){
if(flag){
h=(Node*)malloc(sizeof(Node));
h->data=m->data;
f->next=h;
f=h;
flag=false;
}
m->next=m->next->next;
}
}
}
h->next=NULL;
for(Node* t=p->next;t!=NULL;t=t->next){
if(t->next!=NULL)
printf("%d ",t->data);
else
printf("%d\n",t->data);
}
}
}
}
只可能说是作对了一半,最后还是妥协了。
效果图:

借鉴了网上的大佬改进后写出的代码:
#include<iostream>
#include<cstdlib>
using namespace std;
typedef struct Node{
int data;
Node* next;
}Node,*Linklist;
int main(){
int a;
while(~scanf("%d",&a)){
if(a==0){
printf("list is empty\n");
continue;
}
else{
Linklist L;
L=(Node*)malloc(sizeof(Node));
Node* r;
r=L;
Node* s;
int x;
for(int i=0;i<a;i++){
s=(Node*)malloc(sizeof(Node));
scanf("%d",&x);
s->data=x;
r->next=s;
r=s;
if(i!=a-1)
printf("%d ",s->data);
else
printf("%d\n",s->data);
}
s->next=NULL;
Node* h=L->next;
Node* i=h->next;
while(h&&i){
if(h->data==i->data){
h->next=i->next;
delete(i);
i=h->next;
}else{
h=i;
i=h->next;
}
}
for(Node* t=L->next;t!=NULL;t=t->next){
if(t->next!=NULL)
printf("%d ",t->data);
else
printf("%d\n",t->data);
}
}
}
}
效果图:

此题些许艰辛,最后还是用老套路即用两个指针来指示数据的前后关系,由于前后是递增有序,所以只要把两个指针的关系弄清楚就行了。
最后用数组的方式实现:
#include<iostream>
using namespace std;
int num[100000];
#define inf 100000
int main(){
int a;
while(cin>>a){
for(int i=0;i<a+1;i++){
num[i]=0;
}
if(a==0){
cout<<"list is empty"<<endl;
continue;
}else{
for(int i=0;i<a;i++){
cin>>num[i];
if(i!=a-1)
cout<<num[i]<<" ";
else
cout<<num[i]<<endl;
}
int sum=0;
for(int i=0;i<a-1;i++){
if(num[i]==num[i+1]){
num[i]=inf;
sum++;
}
}
int count=0;
for(int i=0;i<a;i++){
if(num[i]!=inf){
if(count!=a-sum-1){
cout<<num[i]<<" ";
count++;
}else{
cout<<num[i]<<endl;
}
}
}
}
}
}
效果图:

这篇博客探讨了链表的基本操作,包括链表的插入、删除、获取和显示元素,以及链表排序、合并和反转等算法问题。博主分享了在解决这些问题时遇到的挑战和解决方案,包括静态链表和动态链表的实现,并提供了代码示例。

490

被折叠的 条评论
为什么被折叠?



