链表基本操作
链表是数据结构中一种最基本的数据结构,它是用链式存储结构实现的线性表。它较顺序表而言在插入和删除时不必移动其后的元素。现在给你一些整数,然后会频繁地插入和删除其中的某些元素,会在其中某些时候让你查找某个元素或者输出当前链表中所有的元素。
输入
输入数据只有一组,第一行有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”。注:所有的双引号均不输出。
样例输入
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
样例输出
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
提示
提示:
1、因为输入数据中含有大量的插入和删除操作(不管你信不信,反正我信了),所以必须使用链表,否则很可能会超时。这也是考查链表的特性吧。
2、初始化链表的元素是倒序的,这个使用题目中创建列表的方法(从头部插入)就可以了。
总结:
这题考查的是链表的特性。顺序表中,怎样判断何时使用顺序表何时使用链表呢?就要看它们的特点了。顺序表的特点是随机存取、随机访问,也就是说如果存取和查询比较频繁的话使用顺序表比较合适;链表的特点是插入和删除时不必移动其后的节点,如果插入和删除操作比较频繁的话使用链表比较合适。
题解:想着复习一下才学的数据结构一些基础知识,于是就做了这道单链表的题,其实也比较简单,单纯复习下单链表的相关操作的算法
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
using namespace std;
typedef struct node
{
int data;
struct node *next;
}LNode,*LinkList;
LinkList L;
LNode *head=(LNode *)malloc(sizeof(LNode)); //头结点
/**创建单链表*/
LNode *great_L()
{
L=head;
LNode *r=head;
int a[1000]; //由于个人不喜欢从头部插入,于是就定义了一个数组用来实现从尾部插入
int t;
scanf("%d",&t);
int num1;
for(int i=1;i<=t;i++)
{
scanf("%d",&num1);
a[i]=num1;
}
while(t--)
{
LNode *p=(LNode *)malloc(sizeof(LNode));
p->data=a[t+1];
r->next=p;
r=p;
//printf("%d ",r->data); //这里在开始可以判断结点是否插入成功
}
r->next=NULL;
return L;
}
/**打印单链表*/
void show_L(LinkList L)
{
if(L->next==NULL)
{
printf("Link list is empty\n");
}
else
{
LNode *p=L->next;
printf("%d",p->data);
while(p->next!=NULL)
{
p=p->next;
printf(" %d",p->data);
}
printf("\n");
}
}
/**获取链表中某一元素*/
LNode *get_L(LinkList L,int location)
{
LNode *p=L;
int i=0;
while(p->next!=NULL&&i<location)
{
p=p->next;
i++;
}
if(i==location)
return p;
else
return NULL;
}
/**删除链表中某结点*/
int delete_L(LinkList L,int location)
{
LNode *p,*s;
p=get_L(L,location-1); //找到前一结点
if(p==NULL||p->next==NULL) //判断删除操作是否可行
return 0;
else
{
s=p->next;
p->next=s->next;
free(s);
return 1;
}
}
/**插入某一结点*/
int insert_L(LinkList L,int location,int num)
{
LNode *p,*s;
p=get_L(L,location-1); //同样找到前一结点
if(p==NULL)
return 0;
else
{
s=(LNode *)malloc(sizeof(LNode));
s->data=num;
s->next=p->next;
p->next=s;
return 1;
}
}
int main()
{
L=great_L();
int t2;
scanf("%d",&t2);
char str[20];
while(t2--)
{
scanf("%s",str);
if(strcmp(str,"insert")==0)
{
int location;
int num;
scanf("%d%d",&location,&num);
int flag=insert_L(L,location,num);
if(flag==1)
printf("insert OK\n");
else
printf("insert fail\n");
}
if(strcmp(str,"show")==0)
{
show_L(L);
}
if(strcmp(str,"delete")==0)
{
int location;
scanf("%d",&location);
int flag=delete_L(L,location);
if(flag==1)
printf("delete OK\n");
else
printf("delete fail\n");
}
if(strcmp(str,"get")==0)
{
int location;
scanf("%d",&location);
LNode *p=get_L(L,location);
if(p==NULL)
{
printf("get fail\n");
}
else
printf("%d\n",p->data);
}
}
}
仅供自己复习所用,如有错误还望指出