前言

本篇文章的代码中附有注释,可以看一下。代码看起来比较长,其实链表并不难(首先要自信…嗯…)
(此时一个被期末考试逼得肝了几个小时链表题的萌新,留下了他不学无术的泪水)

一、链表的构建

1.尾插法构建链表。输入n个数把它们按输入顺序依次插入到链表中,再依次输出。

#include <stdio.h>
#include <stdlib.h>
struct node//结构体链表基本形式
{
    int data;
    struct node *next;
};
int n,x;
struct node *head,*tail;//定义头指针、尾指针
void insert_after_end(int x)//在链尾插入x
{
    tail->next=(struct node*)malloc(sizeof(struct node));//申请下一个指针的空间
    tail=tail->next;//尾指针向后移一位
    tail->data=x;
    tail->next=NULL;//初始化下一个指针为NULL
}
int main()
{
    scanf("%d",&n);
    head=(struct node*)malloc(sizeof(struct node));//申请头指针空间
    tail=head;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x);
        insert_after_end(x);
    }
    head=head->next;
    while(head!=NULL)
    {
        printf("%d ",head->data);
        head=head->next;
    }
    return 0;
}

2.头插法构建链表。输入n个数把它们逆序插入到链表中,再依次输出。

#include <stdio.h>
#include <stdlib.h>
struct node
{
    int data;
    struct node *next;
};
int n,x;
struct node *H,*head;//H作为头节点,不存储信息,只是起到一个参照物的作用,为了方便理解可以把它当做序号0
void insert_before_begin(int x)//把x插入到头节点的后面,为了方便理解可以当做每次都把x插入到序号0之后,x成为序号1,原序号1后移
{
    head=(struct node*)malloc(sizeof(struct node));
    head->data=x;
    head->next=H->next;
    H->next=head;//这几行代码的作用是把head指针插入到H(序号0)和H的后一个指针(序号1)之间
}
int main()
{
    scanf("%d",&n);
    H=(struct node*)malloc(sizeof(struct node));
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x);
        insert_before_begin(x);
        if(i==1)H->next->next=NULL;//头插法构建链表时,第一个输入的元素是链尾,所以要把它的下一个指针初始化为NULL
    }
    head=H->next;
    while(head!=NULL)
    {
        printf("%d ",head->data);
        head=head->next;
    }
    return 0;
}

二、链表的删除

#include <stdio.h>
#include <stdlib.h>
struct node
{
    int data;
    struct node *next;
};
int n,x;
struct node *p,*head,*tail;
void insert_after_end(int x)
{
    tail->next=(struct node*)malloc(sizeof(struct node));
    tail=tail->next;
    tail->data=x;
    tail->next=NULL;
}
void del(int x)//删除链表中指定元素x
{
    p=(struct node*)malloc(sizeof(struct node));
    p=head;
    while(p->next!=NULL)
    {
        if(p->next->data==x)p->next=p->next->next;
        else p=p->next;
    }
}
int main()
{
    while(scanf("%d",&n)!=-1)
    {
        head=(struct node*)malloc(sizeof(struct node));
        tail=head;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            insert_after_end(x);
        }
        scanf("%d",&x);
        del(x);
        head=head->next;
        while(head!=NULL)
        {
            printf("%d ",head->data);
            head=head->next;
        }
        printf("\n");
    }
    return 0;
}

三、链表的修改

#include <stdio.h>
#include <stdlib.h>
struct node
{
    int data;
    struct node *next;
};
int n,k,x;
struct node *p,*H,*head;
void insert_before_begin(int x)
{
    head=(struct node*)malloc(sizeof(struct node));
    head->data=x;
    head->next=H->next;
    H->next=head;
}
void edit(int k,int x)//将第k个节点的值修改为x
{
    p=(struct node*)malloc(sizeof(struct node));
    p=H->next;
    for(int i=1;i<=n;i++)
    {
        if(i==k){p->data=x;break;}
        else p=p->next;
    }
}
int main()
{
    H=(struct node*)malloc(sizeof(struct node));
    while(scanf("%d",&x)&&x>=0)
    {
        n++;//n记录链表长度
        insert_before_begin(x);
        if(n==1)H->next->next=NULL;
    }
    scanf("%d%d",&k,&x);
    edit(k,x);
    head=H->next;
    while(head!=NULL)
    {
        printf("%d ",head->data);
        head=head->next;
    }
    return 0;
}

四、链表的插入

1.升序给出n个元素,插入到链表中,再插入一个元素后链表元素依然升序排列。

#include <stdio.h>
#include <stdlib.h>
struct node
{
    int data;
    struct node *next;
};
int n,x;
struct node *p,*head,*tail,*newnode;
void insert_after_end(int x)//尾插法构建链表
{
    tail->next=(struct node*)malloc(sizeof(struct node));
    tail=tail->next;
    tail->data=x;
    tail->next=NULL;
}
void insert(int x)//在已经升序排列的链表中插入元素x后,链表仍然升序排列
{
    p=(struct node*)malloc(sizeof(struct node));
    p=head;
    p->data=-1;//把头节点(序号0)赋负值是为了特判插入的x在head->next(序号1)之前的情况
    while(p!=NULL)
    {
        if( x > p->data && x < p->next->data )
        {
            newnode=(struct node*)malloc(sizeof(struct node));
            newnode->data=x;
            newnode->next=p->next;
            p->next=newnode;
            break;
        }
        p=p->next;
    }
}
int main()
{
    while(scanf("%d",&n)!=-1)
    {
        head=(struct node*)malloc(sizeof(struct node));
        tail=head;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            insert_after_end(x);
        }
        scanf("%d",&x);
        insert(x);
        head=head->next;
        while(head!=NULL)
        {
            printf("%d ",head->data);
            head=head->next;
        }
        printf("\n");
    }
    return 0;
}

2.乱序给出n个元素,链表中依次插入这n个元素,同时进行排序。

#include <stdio.h>
#include <stdlib.h>
struct node
{
    int data;
    struct node *next;
};
int n,x;
struct node *p,*H,*newnode;
void insert(int x)//链表中插入x,并保持升序排列
{
    p=H;
    while(p!=NULL)
    {
        if(p->next==NULL)
        {
            p->next=(struct node*)malloc(sizeof(struct node));
            p=p->next;
            p->data=x;
            p->next=NULL;
            break;
        }
        else
        {
            if( x > p->data && x < p->next->data )
            {
                newnode=(struct node*)malloc(sizeof(struct node));
                newnode->data=x;
                newnode->next=p->next;
                p->next=newnode;
                break;
            }
        }
        p=p->next;
    }
}
int main()
{
    while(scanf("%d",&n)!=-1)
    {
        H=(struct node*)malloc(sizeof(struct node));
        H->data=-1;//初始化头节点,赋负值
        H->next=NULL;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            insert(x);
        }
        p=H->next;
        while(p!=NULL)
        {
            printf("%d ",p->data);
            p=p->next;
        }
        printf("\n");
    }
    return 0;
}

五、链表的基本应用-用链表处理结构体排序问题

nefu 1049 cc-test08-1链表的输入与输出

这题相当于上一题的升级版。
上题是结构体中只有data这一个变量,要求把n个元素插入到链表中并要求按data升序排列。
这题是结构体中有num,name,sum等多个变量,要求把每个学生的全部信息插入到每个链表中并要求按sum降序排列(按总成绩从高到低排序输出),按照上一题的代码改编一下就行了,代码看起来很长,其实很简单的啦~

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
    int num;
    char sex,name[21];
    double a,b,c,ave,sum;
    struct node *next;
};
int n,x,num;
char sex,name[21];
double a,b,c,sum;
struct node *p,*head,*newnode;
void insert(int num,char name[21],char sex,double a,double b,double c)
{
    p=head;
    sum=a+b+c;
    while(p!=NULL)
    {
        if(p->next==NULL)
        {
            p->next=(struct node*)malloc(sizeof(struct node));
            p=p->next;
            p->num=num;
            strcpy(p->name,name);
            p->sex=sex;
            p->a=a;
            p->b=b;
            p->c=c;
            p->sum=sum;
            p->ave=p->sum/3;
            p->next=NULL;
            break;
        }
        else
        {
            if( sum < p->sum && sum > p->next->sum )
            {
                newnode=(struct node*)malloc(sizeof(struct node));
                newnode->num=num;
                strcpy(newnode->name,name);
                newnode->sex=sex;
                newnode->a=a;
                newnode->b=b;
                newnode->c=c;
                newnode->sum=sum;
                newnode->ave=sum/3;
                newnode->next=p->next;
                p->next=newnode;
                break;
            }
        }
        p=p->next;
    }
}
int main()
{
    scanf("%d",&n);
    head=(struct node*)malloc(sizeof(struct node));
    head->sum=0x3f3f3f3f;//赋值头节点为INF后可以特判插入的成绩比第一个元素大的情况
    head->next=NULL;
    for(int i=1;i<=n;i++)
    {
        scanf("%d %[^\n] %c%lf%lf%lf",&num,name,&sex,&a,&b,&c);
        insert(num,name,sex,a,b,c);
    }
    head=head->next;
    while(head!=NULL)
    {
        printf("%d %s %c %.2lf %.2lf %.2lf %.2lf %.2lf\n",head->num,head->name,head->sex,head->a,head->b,head->c,head->ave,head->sum);
        head=head->next;
    }
    return 0;
}

————————————————————————————————————————————————————

期末考试题

输入一行字符串,以空格分割成多个字符串,以换行结束,要求逆序输出这多个字符串。
Sample Input:
ljw ak ac
Sample Output:
ac
ak
ljw

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
    char *data;//此处是用的指针表示一维数组
    struct node *next;
};
struct node *p,*H,*head;
struct node* creat()
{
    char in[110],tmp[110];
    gets(in);
    int cnt=0,cnt1=0;
    H=(struct node*)malloc(sizeof(struct node));
    in[strlen(in)]=' ';
    for(int i=0;i<=strlen(in);i++)
    {
        if(in[i]!=' ')tmp[cnt++]=in[i];
        else
        {
            cnt1++;
            p=(struct node*)malloc(sizeof(struct node));
            p->data=(char*)malloc(strlen(tmp)*sizeof(char));//指针一定要先申请空间再使用!!!
            strcpy(p->data,tmp);
            p->next=H->next;
            H->next=p;
            if(cnt1==1)H->next->next=NULL;
            cnt=0;
            memset(tmp,0,sizeof(tmp));
        }
    }
    return H;
}
int main()
{
    head=(struct node*)malloc(sizeof(struct node));
    head=creat();
    head=head->next;
    while(head!=NULL)
    {
        printf("%s\n",head->data);
        head=head->next;
    }
    return 0;
}