链表的引入和简单应用

链表的引入和简单应用 ##

@超人不是人

首先我们先引入一个问题:如何让一个用户记录自己一年当中所看过的电影(包括电影名字和用户对它的评价)。

我们用一个结构来记录情况

struct film
{
    char title[TSIZE];
    int rating ;
}

我们下面简单用几种方式来记录信息

  1. 程序自定义片名的字符个数(TSIZE)和电影的部数(FMAX)。
struct film movies[FMAX];

缺点:程序浪费大量的空间(片名字符个数因不同的电影而不同)和电影的部数会因不同的用户而不同。不能方便修改。

2.用户自个设定(片名的字符长度和电影的部数),分配合适的存储空间
n设为电影的部数

struct film *movies;
movies=(struct film*)malloc(n*sizeof(struct film));

缺点:都是自己规定死了,不能随时随地的修改,否则也会占用大量内存

3.每次写film是,分配一个内存空间(只足够一个film)
缺点:不能保证每次都是连续的存储空间,且每次都要一个变量来存储此单元。

4创建一个大的指针数组并在分配新结构时逐个对这些指针赋值

struct film *movie[FAMX];

缺点:FMAX依然不能灵活变通,虽然同样的个数的数组比指针内存少的多,但依然存在着浪费(本质问题还没有解决)。

5.最后,引用链表的概念:每次使用malloc分配空间时,也为新的指针分配新的内存空间

方法:需要用另外一个指针来跟踪新分配的指针
创建新的结构时,用前一个结构来存储它的地址。

struct film
{
    char title[TSIZE];
    int rating ;
    struct film *next;//定义指向下一个同样结构的指针
}

第五点就是我们链表的结构的基础了。

## 何为链表呢 ##
按我自己来理解,就是一个结构体指向下一个结构体,下一个又指向下一个结构体,直到最后。
相对于数组来说
优点:内存存储空间大大减少,操作(插入,删除等)元素方便
缺点:理解起来相对的吃力,申请管理空间难度大。
我们先来流程图看一下链表

这里写图片描述
每个结构体的next都指向下一个结构体,current是当前的操作的链表,即可以是head,footer,也可以是其他的结构体。
初始化结构体

先说一下我们要实现的功能:一开始要输入所看的电影名字和标号,然后可以根据提示(1删除,2增加,3退出)新的结构体

struct film
{
    char title[SIZE];
    int rating;
    struct film *next;
};
typedef struct film movies;
movies *setup()
{
    int flag=1,a;
    char input[SIZE];
    movies *head=NULL;
    movies *footer,*current;
    printf("请输入第一个电影名字\n");
    while(flag)
    {
        scanf("%s",input);
        /*每次都分配一个新的空间*/
        current=(movies*)malloc(sizeof(movies));

        if(head==NULL)
            head=current;
        else
            footer->next=current;
    /*输入变量值*/   
        current->next=NULL;
        strcpy(current->title,input);
        printf("这是第几部影片\n");
        scanf("%d",&current->rating);
        fflush(stdin);//可以让输入增加容错率,具体百度
        printf("你要继续(按1)还是退出(按0)");
        scanf("%d",&flag);
        fflush(stdin);
        if(flag!=0)
        printf("请输入下一部影片的名字");
    /*保存当前的值*/
        footer=current;
    }
    return head;
}

这里写图片描述

在里面插入新的结构体和删除其中一个结构体

void insert(movies *ptr,int n)//在第n行插入数据
{
    movies *p1,*p2,*swap;
    int i;//数数
    p1=(movies*)malloc(sizeof(movies));
    printf("请输入你要插入的电影题目");
    scanf("%s",&p1->title);
    fflush(stdin);
    printf("请输入电影的标号");
    scanf("%d",&p1->rating);
    fflush(stdin);
    p2=ptr;
    /*这个for的意思是找到要插入的p2的位置*/
    for (i=0;i<n-1;i++)
    {
        p2=p2->next;
    }

    swap=p2->next;
    p2->next=p1;
    p1->next=swap;
    /*这三句我曾经用下面几句话替代,发现地址有冲突,要用一个新的movies结构体(swap)来保存交换的值,p1是插入的结构体,需要仔细的琢磨*/
    //p2->next=current->next;
    //current->next=p2;

}
void cutdown(movies *ptr,int n)//删除其中一个
{
    int i;
    movies *swap;
    for (i=0;i<n-2;i++)
    {
        ptr=ptr->next;
    }
    swap=ptr->next->next;
    ptr->next=swap;
}

void printfdown(movies *pr)         //输出函数
{
    movies *p3;
    p3=pr;
    while(p3!=NULL)
    {
        printf("The film title:%s,rating:%d\n",p3->title,p3->rating);
        p3=p3->next;
        //要用一个p3->next连续指向下一个p3,达到连续输出的结果
    }
}

main函数

void main (void)        //创建n层链表
{
    movies *head,*current;
    int function=0,a=0;
    head=setup();//把头结构地址赋给head
    while(function!=3)
    {
    printf("删除请按1,增加请按2,退出请按3\n");
    scanf("%d",&function);
    if(function==3) break;
    printf("第几行");
    scanf("%d",&a);
    current=head;//需要用head导航,寻找位置
    switch(function)
        {
            case 1:cutdown(current,a);break;
            case 2:insert(current,a);break;
            case 3:break;
        }
    }
    current=head;
    printfdown(current);

}

最后:我一开始接触时遇到很多的大大小小问题,这里就通过注释写出来,但是又有很多没有特别标注

第一篇

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值