1.头文件

#ifndef __LINKLIST_H__
#define __LINKLIST_H__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <math.h>

#define TRAVERSE printf("traverse: %s-%d\n", traverse(head)?"SUCCESS":"FAIL", __LINE__) // 遍历,输出行号

typedef struct linklist
{
    int data;
    struct linklist* next;
}*Linklist, LNode;

/*
链表的遍历
@param head 链表头结点
@return 遍历成功返回true,失败返回false
*/
bool traverse(Linklist head);

/*
带头结点的链表头插
@param head 链表头结点
@param data 插入数据
@return 插入成功返回true,失败返回false
*/
bool insertHead(Linklist* head, int data);

/*
带头结点的链表尾插
@param head 链表头结点
@param data 插入数据
@return 插入成功返回true,失败返回false
*/
bool insertTail(Linklist* head, int data);

/*
带头结点的链表头删(删除第一个节点)
@param head 链表头结点
@return 删除成功返回true,失败返回false
*/
bool deleteHead(Linklist* head);

/*
带头结点的链表尾删(删除最后一个节点)
@param head 链表头结点
@return 删除成功返回true,失败返回false
*/
bool deleteTail(Linklist* head);

/*
在某一位置插入节点(默认从1开始,第0个位置为链表的头结点)
@param head 链表头结点
@param data 插入数据
@param index 插入位置
@return 插入成功返回true,失败返回false
*/
bool insertByIndex(Linklist* head, int data, int index);

/*
删除某一位置的节点(默认从1开始,第0个位置为链表的头结点)
@param head 链表头结点
@param index 删除位置
@return 删除成功返回true,失败返回false
*/
bool deleteByIndex(Linklist* head, int index);

/*
删除某一值等于目标值的节点(多个相等全部删除)
@param head 链表头结点
@param data 目标值
@param returnArr 数组的指针,存储下标个数,以及下标值
@return 删除成功返回true,失败返回false
*/
bool deleteByValue(Linklist* head, int data, int *returnArr);

/*
修改链表某一位置的元素值(默认从1开始,第0个位置为链表的头结点)
@param head 链表头结点
@param data 目标值
@param index 目标位置
@return 修改成功返回true,失败返回false
*/
bool updateByIndex(Linklist* head, int data, int index);

/*
修改链表中元素值等于目标值的节点(多个相等全部修改)
@param head 链表头结点
@param data 目标值
@param newData 新值
@return 修改成功返回true,失败返回false
*/
bool updateByValue(Linklist* head, int data, int newData);

/*
链表的逆置
@param head 链表头结点
@return 逆置成功返回true,失败返回false
*/
bool reverse(Linklist* head);

/*
链表的排序
@param head 链表头结点
@param mode 排序方式,0为升序,1为降序
@return 排序成功返回true,失败返回false
*/
bool sort(Linklist head, int mode);

/*
查找链表倒数第n个节点
@param head 链表头结点
@param n 倒数第n个节点
@return 查找成功返回节点数据域的值,失败返回-1
*/
int findLastN(Linklist head, int n);

/*
释放链表的所有节点
@param head 链表头结点
@return 释放成功返回true,失败返回false
*/
bool freeLinklist(Linklist* head);
#endif

2.源文件

#include "linklist.h"
int main(int argc, char const *argv[])
{
    Linklist head = (Linklist)malloc(sizeof(LNode)); // 创建头节点
    head->data = 0;
    head->next = NULL;

    for(int i = 0; i < 10; i++)
    {
        insertTail(&head, i);
    }
    TRAVERSE;

    // printf("deleteHead: %s-%d\n", deleteHead(&head)?"SUCCESS":"FAIL", __LINE__);
    // TRAVERSE;

    // printf("deleteTail: %s-%d\n", deleteTail(&head)?"SUCCESS":"FAIL", __LINE__);
    // TRAVERSE;

    // printf("insertByIndex: %s-%d\n", insertByIndex(&head, 4, 2)?"SUCCESS":"FAIL", __LINE__);
    // TRAVERSE;

    // printf("deleteByIndex: %s-%d\n", deleteByIndex(&head, 2)?"SUCCESS":"FAIL", __LINE__);
    // TRAVERSE;

    // int *arr;
    // deleteByValue(&head, 0, arr);
    // printf("num:%d\n", arr[0]);
    // for (int i = 0; i < arr[0]; i++)
    // {
    //     printf("%d ", arr[i + 1]);
    // }
    // puts("");
    // TRAVERSE;

    // updateByIndex(&head, 3, 3);
    // TRAVERSE;
    
    // updateByValue(&head, 3, 9);
    // TRAVERSE;

    // reverse(&head);
    // TRAVERSE;

    // sort(head, 1);
    // TRAVERSE;

    //printf("%d\n", findLastN(head, 1));

    freeLinklist(&head);
    TRAVERSE;
    return 0;
}

bool traverse(Linklist head)
{
    if(head == NULL)
        return false;
    int cnt = 0;
    LNode* p = head;
    while (p)
    {
        printf("%d ", p->data);
        p = p->next;
        cnt++;
    }
    puts("");
    if(cnt - 1 == head->data)
        return true;
    else
        return false;
}

bool insertHead(Linklist* head, int data)
{
    if((*head) == NULL)
        return false;
    LNode* newNode = (Linklist)malloc(sizeof(LNode));
    if(newNode == NULL)
        return false;

    newNode->data = data;
    newNode->next = NULL;

    newNode->next = (*head)->next;
    (*head)->next = newNode;
    (*head)->data++;
    return true;
}

bool insertTail(Linklist* head, int data)
{
    if((*head) == NULL)
        return false;
    LNode* newNode = (Linklist)malloc(sizeof(LNode));
    if(newNode == NULL)
        return false;

    newNode->data = data;
    newNode->next = NULL;
    (*head)->data++;

    LNode* t = *head;
    while (t->next) { t = t->next;} // 找到尾节点
    t->next = newNode;
    return true;
}

bool deleteHead(Linklist* head)
{
    if((*head)->next == NULL)
        return false;
    
    LNode* p = (*head)->next;
    (*head)->next = p->next;
    (*head)->data--;
    free(p); p = NULL;
    return true;
}

bool deleteTail(Linklist* head)
{
    if((*head)->next == NULL)
        return false;

    LNode* p = *head;
    while(p->next->next) {p = p->next;}

    LNode* q = p->next;
    free(q); q = NULL;

    p->next = NULL;
    (*head)->data--;
    return true;
}

bool insertByIndex(Linklist* head, int data, int index)
{
    if(index < 1 || index > (*head)->data)
        return false;

    LNode* newNode = (Linklist)malloc(sizeof(LNode));
    newNode->data = data;
    newNode->next = NULL;

    LNode* p = *head;
    for(int i = 0; i < index - 1; i++)
    {
        p = p->next; // 找到插入位置的前一个节点
    }
    newNode->next = p->next;
    p->next = newNode;
    (*head)->data++;
    return true;
}

bool deleteByIndex(Linklist* head, int index)
{
    if(index < 1 || index > (*head)->data)
        return false;

    LNode* p = *head;
    for(int i = 0; i < index - 1; i++)
    {
        p = p->next; // 找到删除位置的前一个节点
    }

    LNode* q = p->next;
    p->next = q->next;
    free(q); q = NULL;
    (*head)->data--;
    return true;
}

bool deleteByValue(Linklist* head, int data, int *returnArr)
{
    if((*head)->next == NULL)
        return false;
    
    int count = 0;
    LNode* p = (*head)->next;
    LNode* prev = *head;
    int index = 1;  

    while (p != NULL)
    {
        if (p->data == data)
        {
            returnArr[++count] = index;  
            prev->next = p->next;        
            free(p);                    
            p = prev->next;              
            (*head)->data--;             
        } 
        else 
        {
            prev = p;                    
            p = p->next;
        }
        index++;
    }
    if(count == 0)
        return false;
    
    returnArr[0] = count;
    return true;
}

bool updateByIndex(Linklist* head, int data, int index)
{
    if(index < 1 || index > (*head)->data)
        return false;

    LNode* p = *head;
    for(int i = 0; i < index; i++)
    {
        p = p->next; // 找到修改的节点
    }
    p->data = data;
    return true;
}

bool updateByValue(Linklist* head, int data, int newData)
{
    if((*head)->next == NULL)
        return false;
    
    LNode* p = (*head)->next;
    while (p != NULL)
    {
        if (p->data == data)
        {
            p->data = newData;
        }
        p = p->next;
    }
    return true;
}

bool reverse(Linklist* head)
{
    if((*head)->next == NULL)
        return false;
    if((*head)->data == 1)
        return true;
    
	Linklist current = (*head)->next->next;
	(*head)->next->next = NULL;
	while(current != NULL){
		Linklist p = current;
		current = current->next;
		p->next = (*head)->next;
		(*head)->next = p;
	}

    return true;
}

bool sort(Linklist head, int mode)
{
    if(head->next == NULL)
        return false;
    
    if(mode == 0)
    {
        for(int i = 0; i < head->data - 1; i++)
        {
            Linklist current = head->next;
            while(current->next != NULL)
            {
                if(current->data > current->next->data)
                {
                    int temp = current->data;
                    current->data = current->next->data;
                    current->next->data = temp;
                }
                current = current->next;
            }
        }
    }
    else if(mode == 1)
    {
        for(int i = 0; i < head->data - 1; i++)
        {
            Linklist current = head->next;
            while(current->next != NULL)
            {
                if(current->data < current->next->data)
                {
                    int temp = current->data;
                    current->data = current->next->data;
                    current->next->data = temp;
                }
                current = current->next;
            }
        }
    }
    return true;
}

int findLastN(Linklist head, int n)
{
    if(head->next == NULL)
        return -1;
    
    if(n > head->data || n < 1)
        return -1;

    LNode* q = head->next;

    LNode* p = head->next;
    for(int i = 0; i < n; i++)
    {
        p = p->next;
    }
    while(p != NULL)
    {
        q = q->next;
        p = p->next;
    }
    return q->data;
}

bool freeLinklist(Linklist* head)
{
    if((*head) == NULL)
        return true;
    LNode* p = (*head);
    while(p != NULL)
    {
        LNode* q = p->next;
        free(p); p = NULL;
        p = q;
    }

    *head = NULL; // 将头指针设置为 NULL 防止悬挂指针
    return true;
}

(PS:链表为带头结点的单链表)