【数据结构2】带头结点·单向链表实现

目录

一、带头结点单向链表

二、接口设计

三、接口实现

[3.1 创建链表](#3.1 创建链表)

[3.2 链表头插](#3.2 链表头插)

[3.3 任意合法位置插入](#3.3 任意合法位置插入)

[3.4 删除元素](#3.4 删除元素)

[3.5 遍历链表](#3.5 遍历链表)

[3.6 释放表和空间](#3.6 释放表和空间)


一、带头结点单向链表

由于后续还有带头指针单向链表,把节点结构定义在common.h中

复制代码
C

typedef int Element_t;
// 节点结构
typedef struct _node
{
    Element_t val;
    struct _node *next;    //节点的下一节点
}Node_t;

带头结点单向的链表头结构

复制代码
C

typedef struct
{
    Node_t head;  //定义一个空间
    int count;
}LinkList_t;

二、接口设计

1、创建链表

2、链表头插

3、链表任意合法位置插入

4、删除链表中某个元素

5、遍历链表中所有元素

6、释放表和空间

复制代码
C

LinkList_t *createLinkList();
void releaseLinkList(LinkList_t *table);

int insertLinkListHeader(LinkList_t * table,Element_t val);
int insertLinkListPos(LinkList_t * table,int pos,Element_t val);

int deleteLinkListElement(LinkList_t *table,Element_t val);

void showLinkList(const LinkList_t * table);

三、接口实现

3.1 创建链表
复制代码
C

LinkList_t *createLinkList()
{
    // 定义一个表
    LinkList_t *table = NULL; 
    // 堆上申请空间
    table = malloc(sizeof(LinkList_t));  
    if (table == NULL)
    {
        return NULL;
    }

    // 初始化
    table->head.val = 0;
    table->head.next = NULL;;
    table->count = 0;

    return table;
}
3.2 链表头插
复制代码
C

int insertLinkListHeader(LinkList_t* table, Element_t val)
{
    // 带头结点常用做法
    Node_t *p = &table->head;

    Node_t *new_node = malloc(sizeof(Node_t));
    if (new_node == NULL)
    {
        return -1;
    }
    new_node->val = val;

    //节点插入
    new_node->next = p->next;
    p->next = new_node;

    ++table->count;
    return 0;
}
3.3 任意合法位置插入
复制代码
C

int insertLinkListPos(LinkList_t* table, int pos, Element_t val)
{
    // 位置合法性判断
    if (pos < 0 || pos > table->count)
    {
        printf("insert pos invalid\n");
        return -1;
    }
    // 找到p == pos-1位置,插入位置的前一个位置
    Node_t *p = &table->head;
    int index = -1;
    while (index < pos-1)
    {
        p = p->next;
        ++index;
    }
    if (p == NULL)
    {
        return -1;
    }
    Node_t *new_node = malloc(sizeof(Node_t));
    new_node->val = val;
    // 节点插入
    new_node->next = p->next;
    p->next = new_node;

    ++table->count;

    return 0;
}
3.4 删除元素
复制代码
C

int deleteLinkListElement(LinkList_t* table, Element_t val)
{
    Node_t *p = &table->head; 
    while (p->next)
    {
        if (p->next->val == val)
        {
            break;
        }
        p = p->next;
    }

    if (p->next == NULL)
    {
        printf("not find\n");
        return -1;
    }
    // 删除元素
    Node_t* tmp = p->next;
    p->next = tmp->next;

    free(tmp);
    --table->count;

    return 0;
}
3.5 遍历链表
复制代码
C


void showLinkList(const LinkList_t* table)
{
    // 访问head下一个节点
    Node_t *p = table->head.next;
    printf("link list:%d\n",table->count);

    while (p)
    {
        printf("%d\t",p->val);
        p = p->next;
    }
    printf("\n");
}
3.6 释放表和空间
复制代码
C


void releaseLinkList(LinkList_t* table)
{
    if (table)
    {
        Node_t *p = &table->head;
        Node_t *tmp;
        while (p->next)
        {
            tmp = p->next;
            p->next = tmp->next;

            free(tmp);
            --table->count;
        }
        printf("table have %d element\n",table->count);
        free(table);    //相当于把表头也释放了
    }
}

如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!

相关推荐
aramae6 小时前
MySQL复合查询(8)
java·c语言·开发语言·后端·算法
荆棘鸟智能7 小时前
城市感知设备怎么统一接入?从多协议网关到设备模型的中间件架构设计
人工智能·算法·边缘计算
无敌贵点大王7 小时前
RTThread学习记录11——RT-Thread 设备模型吃透:UART/ADC/PWM/PIN 到底有什么区别?
c语言·stm32·学习·链表
淡海水7 小时前
13-04-面试-源码级深度追问链
数据结构·unity·面试·c#·游戏引擎·源码·il2cpp
Logic1018 小时前
C语言/数据结构位运算题解:异或XOR找出时尚聚会中的“独特颜色“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
INGNIGHT11 小时前
270 · 电话号码的字母组合II(Trie)
linux·算法
2401_8390805411 小时前
C++常见八股
数据结构·c++·算法
青山是哪个青山12 小时前
LeetCode 188:买卖股票的最佳时机 IV
算法
暮雨封夕12 小时前
跳表(Skip List)详解:原理、实现、使用场景与实际应用
数据结构
mikuyyds12 小时前
geo-toolbox 插件算法解析:RUSLE 与 MUSLE 的工程化落地
算法·rust·gis