链表的复习----头插与尾插有头链表

#此文章用于大一C语言的链表复习

这里就不再上链表官方定义了,直接说我对链表的理解。链表相当于内存中一系列不连续的地址通过指针相互联系在一起,它需要通过结构体来实现,同时引入了节点的概念,即以前我们通过一个变量来储存数据,现在在链表中用节点来储存数据,因为在链表中,一个数据总伴随着一个指向下一个数据地址的指针,所以这种形式的变量需要用结构体来实现,一个结构体变量里有存储数据的子变量,还有存储下一个结构数据的指针变量,这种形式很像火车车厢,有装载货物的地方,还有连接下一个车厢的钩子,一个节点中的指针变量就相当于那个钩子。

我画了一个图,我意识中的链表就是这样的,老师也这样画过。

之后是链表的基本操作

一.创建一个链表

1.头插法创建一个有头链表

#include <stdio.h>
#include <stdlib.h>//需要用到malloc函数
struct link
{
    int data;//用于存储数据的地方
    struct link *next;//用于指向下一个节点的指针
};//先创建结构体
int main(void)
{
    struct link *head,*s;
    head=(struct link*)malloc(sizeof(struct link));//首先要让指针head指向一块可供存储的空间,否则无法对其操作
    head->next=NULL;//由于head只是一个单独的存在,所以下一个指向空
    while(1)
    {
        s=(struct link*)malloc(sizeof(struct link));//让s指向一块可供存储的空间
        scanf("%d",&s->data);//对s赋值
        if(s->data==-1)//终止链表输入的条件
            break;
        s->next=NULL;//s的下一个指向空
        s->next=head->next;//要断开head与它的下一个,把s插进去,所以必须先保存head的下一个的地址,即把head的下一个的地址给s的next指针
        head->next=s;//连接head与s,反复此过程可进行连续的链表插入
    }
    head=head->next;//这里附上一个指针输出,以供直观测试
    while(head!=NULL)
    {
        printf("%d ",head->data);
        head=head->next;
    }
    return 0;
}

附录1:这里是一个能进行连续头插的方法,只需重复这两步就能实现连续的头插,但如果要生成一个正规可用的链表,则要求初始的单节点的next指针必须指向空。

附录2:在操作一个指针时,如果想给指针直接赋值,指针必须要指向一块有存储空间的地址,否则无法操作。指针最好先指向空,否则初始指针的指向是随意的,乱用可能会造成系统崩溃等一些严重的问题。

附录3:头插法按顺序输出是与输入是的顺序反向的,所以在做链表逆序的题时会用到头插法。

2.尾插法创建一个有头链表。

#include <stdio.h>
#include <stdlib.h>//需要用到malloc函数
struct link
{
    int data;//用于存储数据的地方
    struct link *next;//用于指向下一个节点的指针
};//先创建结构体
int main(void)
{
    struct link *head,*tail,*s;//这里需要再声明一个tail进行尾插
    head=(struct link*)malloc(sizeof(struct link));//首先要让指针head指向一块可供存储的空间,否则无法对其操作
    head->next=NULL;//由于head只是一个单独的存在,所以下一个指向空
    tail=head;//一开始tail与head指向重合
    while(1)
    {
        s=(struct link*)malloc(sizeof(struct link));//让s指向一块可供存储的空间
        scanf("%d",&s->data);//对s赋值
        if(s->data==-1)//终止链表输入的条件
            break;
        s->next=NULL;//s的下一个指向空
        tail->next=s;//tail的next指针指向s,二者连接起来
        tail=s;//s成为下一个tail,下一个循环中又会有一个新的s插到后面,如此循环,最终创建好一个链表
    }
    head=head->next;//这里附上一个指针输出,以供直观测试
    while(head!=NULL)
    {
        printf("%d ",head->data);
        head=head->next;
    }
    return 0;
}

附录:尾插法的顺序是正常的,所以这也是一种非常常用的链表创建方法

关于有头节点的一个总结:由于创建时第一个节点的一些特殊性,导致有时第一个节点有值时会出现一些麻烦的情况,所以这时有一个数据为空的头节点有一些优势,同时有头节点在创建时思路较为简单,可操作性也很强,但有时会比无头节点多一步,会麻烦一些。

这里先写有头节点,因为我发现我对无头节点链表的理解并不是很透彻,同时我自己仿照书上的方法写了一个无头链表,发现我的编译器对其有报错,我打算换个编译器再试试,所以为了避免打扰其他人的思维,我先到此为止。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值