首页 > 其他分享 >[数据结构10分钟入门] 面向初学者从零实现 -- 单链表

[数据结构10分钟入门] 面向初学者从零实现 -- 单链表

时间:2022-09-07 19:11:22浏览次数:81  
标签:node 10 -- list next 链表 初学者 节点 指针

一、链表是什么

链表是一种通过指针串联在一起的线性结构,在内存中是分散存储的(数组在内存中连续分布),链表由一系列节点组成,每个节点都由数据域和指针域组成。主要有三种类型的链表:

1、单链表(本章介绍内容)

2、双链表

3、循环链表

链表与数组对比:

插入/删除 时间复杂度 查询 时间复杂度 适用场景
数组 O(n) O(1) 内容固定,查询较为频繁
链表 O(1) O(n) 内容不固定,较少查询

二、单链表定义

1、一个单链表的节点:

  • 数据域data:存放数据的地方
  • 指针域*next:指向下一个节点的地址

2、将节点链接起来,每个节点的*next指针指向下一节点,最后一个节点的指针指向NULL,就形成了单链表。

3、头指针的作用

设置一个头指针指向整条链表的首节点,这样对首节点的操作将和其余节点一致,无需使用两套处理逻辑。‍

三、节点结构体


typedef struct node {
    int data;   /**数据域*/
    struct node *next;    /**指向下一个节点*/      
}list_node;

因为每个节点的数据结构都是一样的,都为struct node,所以指针域*next的类型也是struct node。

四、创建链表


list_node* list_init()
{
    /**从内存动态申请 #1*/
    list_node *head = (list_node *)malloc(sizeof(list_node));
    /** #2*/
    if(head == NULL) {
        return NULL;
    }
    /**初始化头指针 #3*/
    head->data = 0;
    head->next = NULL;  //链表暂无节点,指针赋为NULL
    /** #4*/
    return head;
}

1、malloc动态申请list_node大小(8个字节)的内存,作为链表的头指针;

2、if(head == NULL) 对malloc的返回值进行判断;

3、初始化头指针,头指针的数据域data没有什么作用,可以用来代表链表的节点数量;

4、返回头指针。

五、插入节点


int list_insert(list_node *head, int data, int pos/** #1*/)
{
    list_node *p = head;

    /**如果要插入的位置比链表长,则属于非法操作 #2*/
    if (pos > p->data) {
        return -1;
    }

    /**动态申请一个节点*/
    list_node *node = (list_node *)malloc(sizeof(list_node));
    if (node == NULL) {
        return -1;
    }
    node->data = data;
    node->next = NULL;

    /**遍历链表,找到要插入的位置 #3*/
    for (int i=0; i<pos; i++) {
        p = p->next;
    }

    /**插入节点 #4*/
    node->next = p->next;
    p->next = node;

    /**链表长度加1*/
    head->data++;
   
    return 0;
}

1、参数pos代表节点插入的位置,首节点的位置为0;

2、对插入位置进行判断,不能大于链表长度,异常返回-1;

3、遍历链表找到新节点要插在哪个节点之后,p指向这个节点;

4、如下图假设node4要插入到node1与node2之间,此时的p指针指向节点为node1,新创建的节点指针node指向node4;

node->next = p->next; 即为 node4->next=node1->next=node2

p->next = node; 即为 node1->next=node4

六、删除节点


int list_delete_node(list_node *head, int pos)
{
    list_node *p = head;

    /**删除的位置比链表长,则属于非法操作*/
    if (pos > p->data) {
        return -1;      
    }
    /**遍历链表,找到要删除的节点的前一个节点的指针*/
    for (int i=0; i<pos; i++) {
        p = p->next;
    }
    /**记录将被删除的节点, 用于最后释放该节点内存 #1*/
    list_node *p2 = p->next;
   
    /**跳过被删除的节点,释放内存,完成删除 #2*/
    p->next = p->next->next;
    free(p2);
   
    head->data--;
    return 0;
}

1、被删除的节点的内存需要进行释放,避免内存泄漏;

2、如下图,假设要删除node2,则只需直接将node1的next指针指向node3

七、测试

目录结构

./
├── build                    //编译目录
├── CMakeLists.txt    //cmake 配置文件
├── list_01.c               //源码
├── list_01.h
└── test.c                   //测试文件

工程采用cmake构建,文件均经过测试,编译步骤如下:

1、mkdir build && cd build

2、cmake ../ && make

3、./list_test

源码地址在公众号同标题文章底部,公众号:Linux杂货铺

标签:node,10,--,list,next,链表,初学者,节点,指针
From: https://www.cnblogs.com/linux-misc/p/16663657.html

相关文章

  • 10.4类和对象的相关知识
    classFruits:discount=0.8#类变量,静态变量#当所有的变量都用到同一个属性的时候,我们定义一个类变量def__init__(self,name,price):self.nam......
  • Logstash深入收集Nginx日志
    Logstash深入收集Nginx日志安装nginx[root@elkstack03~]#yuminstall-ynginx##主配置文件[root@elkstack03~]#cat/etc/nginx/nginx.confusernginx;worker......
  • 在SystemVerilog中,类成员的private, public, protected 属性分别是什么意思,SystemVerilo
    默认情况下,可以使用类的对象句柄从类外部访问类的成员和方法,即它们是public的。如果我们不希望某些成员和某些方法可以从类外部访问怎么办?为了防止意外修改类成员/方法。,......
  • 分页查询,redis缓存分页数据,redis双重检测
    StringpageKey=RedisKeyManagement.getKey(RedisKeyManagement.ACTIVITY_BAISHI_PAGE_CACHE,Arrays.asList(activityId.toString(),String.valueOf(current)));......
  • Spring Boot项目——统一异常处理
    背景在做项目时,会产生各种各样业务异常,大致可以分为下面几类参数异常:服务端接收客户端参数时,参数不符合规则而产生的问题数据库异常:服务端和数据库交互时发生的异常......
  • 如何把电脑文件传到虚拟机 三种方式
    如何把电脑文件传到虚拟机三种方式方法一:VMWareTools安装VMWaretools,点击上方虚拟机->安装VMwaretools安装成功后,即可通过复制粘贴文件,将文件复制到虚拟机中......
  • 第六章 6 函数-迭代器与生成器 练习题
    第六章6函数-迭代器与生成器练习题[基础知识]1说说python中装饰器、迭代器的用法;描述下dict的items()方法与iteritems()方法的不同;解答:装饰器:装饰器是指对函数......
  • Logstash深入收集Java日志
    Logstash深入收集Java日志没有修改Json格式在企业中,我们看到tomcat日志遇到异常(exception)一条日志可能是几行或者十几行甚至几十行,组成的,那么,我们需要将多行日志变成......
  • 多项式全(?)家桶
    贴个板子,以备复习点击查看代码#include<cstdio>#include<cstdlib>#include<algorithm>#include<unordered_map>#include<cmath>#definemod998244353#definemax......
  • java获取当前日期和前一周、前一月、前一年的日期
    java获取当前日期和前一周、前一月、前一年的日期publicstaticvoidmain(String[]args){SimpleDateFormatformat=newSimpleDateFormat("yyyy-MM-dd......