数据结构之链表增删查改(最详细注释和最清晰思路,附完整代码)

PZK学数据结构之链表(史上最详细思路和代码注释)(完整代码我放在最后面了,可以直接跑,方便大家cv编程)


前言

在增删的指定节点操作就用到了查,大家可以看完增删的前两个就去看看查是怎么操作的,然后方便对指定节点操作。
本篇文章是交大家如何用结构体指针实现增删查改,

一、链表是什么?

百度百科链表:链表是一种物理存储单元上非连续、非顺序的存储结构,
数据元素的逻辑顺序是通过链表中的指针链接次序实现的。

我的理解:多个有指针域的结构体的通过指针顺序链接在一起, 在内存中的存储是散落的

2.1图解数组和链表的存储

在内存如下存储:在这里插入图片描述

---------------------------------------------------------------------------------------------------------------------------------------------------------------

2.2简单实现链表的两种方法,第一种是用结构体,第二种是用结构体指针

代码如下(示例):

2.2.1实现链表1
#include <stdio.h>
#include <stdlib.h>
struct Test//结构体定义
{
   
   
   int data;
   struct Test *next;
};

int main()
{
   
   
   struct Test t1={
   
   1,NULL};
   struct Test t2={
   
   2,NULL};
   struct Test t3={
   
   3,NULL};

   t1.next=&t2;//链表精髓在这,每个节点的next存放的是下一个节点的地址。这样就连接起来了。
   t2.next=&t3;
}
2.2.1实现链表2
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct node
{
   
   
    int data;
    struct node * next;
}node,*pnode;//node是取别名,pnode是类型,结构体指针类型

//struct node *  pnode
//创建头节点,初始化函数。返回头节点的指针。
pnode init()
{
   
   
    pnode head = (pnode )malloc(sizeof(node));   //用malloc开辟空间,此时pnode == struct node *
  
    if(head == NULL)//此时做一个容错判断,如果没有开辟成功,打印错误
    {
   
   
        perror("head fault");
    }
   
    head->data = 0;//开辟空间之后里面是没有值的,最好给数据域和指针域分别赋值
    head->next = NULL;//指针没有指向,指向NULL就ok,防止其乱指向
   
    return head;//返回头节点指针,方便我们以后调用

}


---------------------------------------------------------------------------------------------------------------------------------------------------------------

二、本文实现的几个功能

链表的增加
链表的删除
链表的查找
链表的改动


---------------------------------------------------------------------------------------------------------------------------------------------------------------

三、链表的增加

在内存如下演示:
在这里插入图片描述

实现思路:(博主比较懒,三种插法只详细写了一个思路,思路都大同小异,我在每个插法代码的前面都画了内存操作图,里面有简单思路,每一行代码里面都给了注释,不理解的可以评论区留言呀)
第一步,创建新节点,然后把传递的值赋值给新节点
pnode pnew = (pnode )malloc(sizeof(node));//用malloc开辟空间,类型是pnode,大小是一个结构体的大小

第二步,写一个容错判断,如果pnew==NULL,说明创建不成功,直接退出

第三步:链接新节点到链表头下一个节点,何为链接,无非就是把下个节点的地址赋值给头节点的next;
pnew->next = head->next;//head->next原本存的是第二个节点的地址,现在把它赋值给新节点,那么是不是新节点的下一个就是原先的第二个节点了,就是实现图中1

第四步:把头结点和新节点连接起来
head->next = pnew;//此时,我们在把新节点和头节点链接起来,这样就是头节点指向新节点了,pnew本身就是一个指针


3.1头插法:每次都在头结点的后面插入

//每次都在头结点的后面增加,简称头插法
/****************************************************************
 * 函数名: insertHead
 * 参  数: head  链表的头节点指针
 *         data  需要插入节点数据
 * 返回值: 链表中节点个数
 *         节点的个数保存在head的data中。
 ****************************************************************/
int insertHead(node* head,int data)
{
   
   
    //第一步:创建新节点,存入数据
    pnode pnew = (pnode )malloc(sizeof(node));//用malloc开辟空间,类型是pnode,大小是一个结构体的大小

    if(NULL == pnew)//容错判断新创建的节点是否成功
    {
   
   
        perror("head NULL");
        exit(0);//不成功就输出错误,然后退出
    }
   
    pnew->data = data;//把传进来的值赋值给新节点

    //第二步:链接新节点到链表头下一个节点,何为链接,无非就是把下个节点的地址赋值给头节点的next;
    //head的next为空的情况
    pnew->next = head->next;//head->next原本存的是第二个节点的地址,现在把它赋值给新节点,那么是不是新节点的下一个就是原先的第二个节点了

    //第三步:head不为空,把头节点的next指针指向新的节点
    head->next = pnew;//此时,我们在把新节点和头节点链接起来,这样就是头节点指向新节点了,pnew本身就是一个指针
                      //当第二步赋值的时候,头节点与原先的第二个节点链接自动断开

    //第四步:节点个数加一
    (head->data)++;//因为我们头节点的数据域存的是节点个数
    //第五步:返回头节点中节点数据;
    return head->data;
}

---------------------------------------------------------------------------------------------------------------------------------------------------------------

3.2尾插法:每次都在链表的最后面插入

在内存如下演示:
在这里插入图片描述


/****************************************************************
 * 函数名: insertEnd
 * 参  数: head  链表的头节点指针
 *         data  需要插入节点数据
 * 返回值: 链表中节点个数
 *         节点的个数保存在head的data中。
 ****************************************************************/
int insertEnd(pnode head,int data)
{
   
   
    //第一步:定义临时指针
    node* ptmep = head;
    //第二部:遍历链表,找最后一个节点
    while( ptmep->next != NULL)
    {
   
   
        ptmep = ptmep->next;//指针偏移
    }
    //循环完之后,ptemp的next已经为NULL了
    //第三步:创建新节点
    pnode pnew = (pnode)malloc(sizeof(node));//malloc开辟空间
  
    //第四步:给节点赋值
    pnew->data = data;
    //第五步:新节点插入到链表末尾
    pnew->next = NULL;//尾插法,新节点需放在最后,所以新节点后面没有节点了,指向null
    ptmep->next = pnew;//原最后一个节点指向新节点,那么原最后一个节点就成为了倒数第二个节点
  
    //第六步:返回链表长度
    (head->data)++;
    return head->data;//也可以直接return ++(head->data);一样的效果
    }
   

------------------------------------------------------------------------------------

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值