【数据结构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);    //相当于把表头也释放了
    }
}

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

相关推荐
郝学胜-神的一滴2 小时前
深入浅出链表:数据结构中的“珍珠项链“
开发语言·数据结构·程序人生·链表
近津薪荼2 小时前
优选算法——前缀和(6):和可被 K 整除的子数组
c++·算法
lifallen2 小时前
线性基 (Linear Basis)
数据结构·算法
twilight_4692 小时前
人工智能数学基础——第二章 高等数学基础
人工智能·算法·机器学习
_OP_CHEN2 小时前
【算法提高篇】(二)线段树之区间修改:懒标记的核心奥义与实战实现
算法·蓝桥杯·线段树·c/c++·区间查询·acm/icpc·懒标记
啊阿狸不会拉杆2 小时前
《机器学习导论》第 18 章-增强学习
人工智能·python·学习·算法·机器学习·智能体·增强学习
田里的水稻2 小时前
FA_规划和控制(PC)-D*规划
人工智能·算法·数学建模·机器人·自动驾驶
小跌—2 小时前
Redis数据结构和单线程
数据结构·数据库·redis
We་ct2 小时前
LeetCode 61. 旋转链表:题解+思路拆解
前端·算法·leetcode·链表·typescript