以下是参考Linux链表实现的简易通用链表,目前水平有限,只能理解大概思想,做一个玩具 demo:
后续继续学习后再做补充。
klist.h
#ifndef _KLINK_LIST
#define _KLINK_LIST
/****************************************************************************
* @file : incl/klinklist.h
* @brief : 通用链表
* @author : shachi
* @email : shachi1758@outlook.com
* @details :
* @version : 0.1.0
* @history :
* 2023-03-02 16:29:52 创建文件
* 2023-03-05 15:11:19 实现初始化、头插法。
****************************************************************************/
#include <stdint.h>
#include <stddef.h>
/**
* @brief 通用头节点
*/
struct klist_head{
struct klist_head *prev;
struct klist_head *next;
};
/**
* @brief: 通用链表初始化
* @param1: l,链表头
*
* 前驱和后继都指向自己。
*
*/
inline void klist_init(struct klist_head *head)
{
head->next = head;
head->prev = head;
}
/**
* @brief: 头插法插入节点
* @param1: new,要插入的节点
* @param2: l,要插入的链表
*
* @return: -1,插入失败
* 0,插入成功
*
*/
int32_t klist_add(struct klist_head *new,struct klist_head *head);
/**
* @brief: 删除节点。
* @param1: head,待删除的节点。
*
* 删除链表上的节点,只是从链表中删除,不会释放空间。
*
* @return: -1 失败
* 0 成功
*/
int32_t klist_del(struct klist_head *head);
#endif // _KLINK_LIST
klist.c
/****************************************************************************
* @file : ./src/klink_list.c
* @brief :
* @author : shachi
* @email : shachi1758@outlook.com
* @details :
* @version : 0.1.0
* @history :
* 2023-03-05 14:53:47 创建文件
* 2023-03-05 15:11:19 实现初始化、头插法。
****************************************************************************/
#include "klinklist.h"
int32_t klist_add(struct klist_head *new, struct klist_head *head)
{
if(!head || !new) return -1;
// 原来的第一个节点前驱指针指向新节点。
head->next->prev = new;
// 新节点的后继指针指向原来的第一个节点。
new->next = head->next;
// 头节点的后继指针指向新节点。
head->next = new;
// 新节点的前驱指针指向头节点。
new->prev = head;
return 0;
}
int32_t klist_del(struct klist_head *head)
{
if(!head) return -1;
// 后继节点前驱指针指向待删除节点前一个
head->next->prev = head->prev;
// 前驱节点后继指针指向待删除节点后一个
head->prev->next = head->next;
// 被删除节点的前驱后继指向 NULL
head->prev=NULL;
head->next=NULL;
return 0;
}
main.c
/****************************************************************************
* @file : ./src/main.c
* @brief :
* @author : shachi
* @email : shachi1758@outlook.com
* @details :
* @version : 0.1.0
* @history :
* 2023-03-05 14:17:41 创建文件
****************************************************************************/
#include <malloc.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "klinklist.h"
#include "klogger.h"
struct student{
struct klist_head head;
int32_t id;
int32_t age;
};
int main(int argc, const char* argv[])
{
struct student *st_head = (struct student *) malloc (sizeof(struct student));
// 初始化学生信息链表
klist_init((struct klist_head *)st_head);
// 插入六个学生信息。
for (size_t i = 0; i < 6; ++ i){
struct student *ptr = (struct student*) malloc(sizeof(struct student));
ptr->id = i;
ptr->age = i + 15;
klist_add((struct klist_head *) ptr,(struct klist_head *) st_head);
}
// 打印学生信息
struct klist_head *ptr = st_head->head.next;
while(ptr->next != st_head->head.next) {
printf("id:%d,age:%d\n",((struct student *)ptr)->id,((struct student *)ptr)->age);
ptr = ptr->next;
}
// 删除一些学生信息。
struct klist_head *ptr2 = st_head->head.next;
struct student *ptr_del;
while(ptr2->next != st_head->head.next){
ptr_del = (struct student *)ptr2;
if(ptr_del->age == 16) {
printf("id:%d,age:%d is deleted.\n",ptr_del->id,ptr_del->age);
struct klist_head *tmp = ptr2->next;
klist_del(ptr2);
// 释放空间。
free(ptr2);
ptr2 = tmp;
continue;
}
ptr2 = ptr2->next;
}
// 打印删除后的链表。
struct klist_head *pt = st_head->head.next;
while(pt->next != st_head->head.next) {
printf("id:%d,age:%d\n",((struct student *)pt)->id,((struct student *)pt)->age);
pt = pt->next;
}
return 0;
}
参考: