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

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

相关推荐
磊 子1 分钟前
多态类原理+四种类型转换+异常处理
开发语言·c++·算法
染指11101 小时前
3.AI大模型-token是什么-大模型底层运行机制
人工智能·算法·机器学习
谙弆悕博士2 小时前
快速学C语言——第19章:C语言常用开发库
c语言·开发语言·算法·业界资讯·常用函数
光影少年2 小时前
前端算法题
前端·javascript·算法
南宫萧幕2 小时前
基于 Simulink 与 Python 联合仿真的 eVTOL 强化学习全链路实战
开发语言·人工智能·python·算法·机器学习·控制
电魂泡哥2 小时前
CMS垃圾回收
java·jvm·算法
hkj88082 小时前
CRC-512算法输出64字节
算法
@我漫长的孤独流浪2 小时前
计算机系统核心概念与性能优化全解析
算法·计算机外设
如竟没有火炬3 小时前
接雨水22
数据结构·python·算法·leetcode·散列表