关于链表

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。我们今天以链表的创建,遍历,和删除以及插入操作来深入了解一下链表以及怎么写这些函数(这里皆以最简单的单线链表作为实例)
首先我们来讨论一下怎么进行链表的创建
接下来请欣赏我那注入灵魂的画作
在这里插入图片描述
看不懂没关系待我慢慢给你讲,首先我们
第一步先把链表的头指针head初始化,包括里面的数据和内部指针next的初始化,我们一定要养成一个习惯,申明一个指针时一定要给它初始化,否则极易出现段错误,让尾节点tail等于头节点
第二步使用创建一个new节点来作为后面的新节点,并为它开辟一段内存空间给他使用,并使它的内部指针next为NULL
第三步我们让尾节点的内部指针指向新的的节点,即tail->next=new
最后我再让新的开辟出来的节点作为新的尾节点tail=new;经过这样的四部操作,我们就已经创建好了新的节点
接下来我把源码贴出来:以结构体指针学生作为例子

struct Student *init()
{
     int i;
     struct Student *head;
     struct Student *tail;
     head=(struct Student *)malloc(sizeof(struct Student));
     head->next=NULL;
     head->num=1;
     struct Student *new;
     tail=head;
    for(i=1;i<5;i++)
    {
            new=(struct Student *)malloc(sizeof(struct Student));
            new->next=NULL;
            new->num=i+1;
            tail->next=new;
            tail=new;
    }

    return  head;

}

接下来我继续贴出我的灵魂画作来解释一下链表的遍历,也就是把链表元素用循环的方式输出
也就是一个个输出,其实作为最简单的一种操作,只要注意细节,一般都不会出错
在这里插入图片描述
首先先把头指针传入函数,然后我们声明一个同样的结构体指针p来指向头指针,用一个while循环,只要p不等于NULL,就遍历下去,并且每当遍历一个结构体指针完后,把p->next指向p,也就是此时的p指向的是下一个链表元素,保证每个元素都能遍历到
源代码我也贴上去

void prinfinfo(struct Student *head) {
    struct Student *p;
    p = head;
    while (p != NULL) {
        printf("name is%s,num is %d,score is %.2f\n", p->name, p->num,p->score);
        p = p->next;
    }
}

灵魂画作三:链表的删除
在这里插入图片描述
链表的删除。我假设我要删掉一个成员变量num为2的节点,我该怎么做呢,
一首先我们要用遍历伐找到目标节点的前一个节点,为什么呢?因为前一个节点得内部指针正好是后面目标节点的地址,所以我们得先找这个节点,当然,遍历的条件也很重要,为什么还要加个p->next!=0,因为我们考虑到了如果刚好我们要找的节点是最后一个节点我们怎么办,那不是漏了,遍历的期间把条件作为if语句来一个一个节点找
二找到之后我们要怎样删去节点呢,我们需要引进一个同类型的变量tmp作为一个容器继续操作,先让它把p->next的值存下来,此时p->next的值其实就是要删除的语句的地址,然后再让p->next指向要删除节点的下一个节点,即tmp->next,接下来链表完整了,我们需要把它释放掉,用free语句;删除完就可以跳出循环了
源码在以下

void deletenode(struct Student *head)
{
    struct Student *tmp;
    tmp=NULL;
    struct Student *p;
    p=head;
    while(p!=NULL&&p->next!=NULL)
    {
        if(p->next->num==2)
        {
            tmp=p->next;
            p->next=tmp->next;
            free(tmp);
            break;
        }
        p=p->next;
    }

}

灵魂画作四:链表的插入
在这里插入图片描述
首先我们想插入一个新的链表怎么办呢
一:创建一个节点并为它申请内存和初始化内部指针
struct Student *node;
node=(struct Student *)malloc(sizeof(struct Student));
node->next=NULL;
二:新的节点的内部指针指向下一个节点
struct Student *p;
p=head;
node->num=9;
node->next=p->next;
三让上一个节点next指向node
p->next=node;

源码如下

void insertnode(struct Student *head)
{
    struct Student *node;
    node=(struct Student *)malloc(sizeof(struct Student));
    node->next=NULL;
    struct Student *p;
    p=head;
    node->num=9;
    node->next=p->next;
    p->next=node;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值