数据结构之单链表

122 阅读6分钟

这是我参与更文挑战的第16天,活动详情查看: 更文挑战

链表是数据结构中一种最基本的数据结构,它是用链式存储结构实现的线性表。它较顺序表而言在插入和删除时不必移动其后的元素。现在给你一些整数,然后会频繁地插入和删除其中的某些元素,会在其中某些时候让你查找某个元素或者输出当前链表中所有的元素。


输入


输入数据只有一组,第一行有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);
        }
    }
}


这里给出单链表插入(insert),删除(delete),查找(get),输出(show)等功能,脱离题目可能会更实用点

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
typedef struct node
{
    int data;
    struct node *next;
} LNode,*LinkList;
LinkList L;
LNode *head=(LNode *)malloc(sizeof(LNode));
LNode *creat_L()
{
    L=head;
    LNode *r=head;
    printf("请输入数字用以创建链表,输入0结束\n");
    int num;
    scanf("%d",&num);
    while(num!=0)
    {
        LNode *p=(LNode*)malloc(sizeof(LNode));
        p->data=num;
        r->next=p;
        r=p;
        scanf("%d",&num);
    }
    r->next=NULL;
    return L;
}
void show_L(LinkList L)
{
    if(L->next==NULL)
    {
        printf("Link is empty");
    }
    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=creat_L();
    char str[20];
    printf("请输入相关指令,包括:insert,show,delete,get\n");
    while(~scanf("%s",str))
    {
        if(strcmp(str,"insert")==0)
        {
            printf("请输入你所要插入的地址及数值\n");
            int location;
            int num;
            scanf("%d%d",&location,&num);
            int flag=insert_L(L,location,num);
            if(flag==1)
            {
                printf("insert OK\n");
                printf("插入成功,插入后的链表为:\n");
                show_L(L);
            }
            else
                printf("insert fail\n");
        }
        if(strcmp(str,"show")==0)
        {
            printf("链表为:\n");
            show_L(L);
        }
        if(strcmp(str,"delete")==0)
        {
            printf("请输入需要删除的位置:\n");
            int location;
            scanf("%d",&location);
            int flag=delete_L(L,location);
            if(flag==1)
            {
                printf("delete OK\n");
                show_L(L);
            }
            else
                printf("delete fail\n");
        }
        if(strcmp(str,"get")==0)
        {
            printf("请输入你想要得到数值的位置:\n");
            int location;
            scanf("%d",&location);
            LNode *p=get_L(L,location);
            if(p==NULL)
            {
                printf("get fail\n");
            }
            else
            {
                printf("获取成功,其数值为:\n");
                printf("%d\n",p->data);
            }
        }
    }
    return 0;
}

仅供自己复习所用,如有错误还望指出