相关代码在 https://gitee.com/xping2016/common_function_templates/tree/master/C&C++/LinkedList
关于链表的基本操作
定义链表数据类型,一个是单节点,一个是链表基信息
#include "stdint.h"
//单个链表节点定义
struct _LinkedListSingle{
uint16_t id; /* 标识这个元素方便查找 */
void *data; /* 链表中包含的数据指针 */
struct LinkedListSingle *next; /* 指向下一个链表的指针 */
};
typedef struct _LinkedListSingle LinkedListSingle;
//总链表节点定义
typedef struct{
LinkedListSingle *head;//链表头的地址
LinkedListSingle *tail;//最后一个节点的地址
int length; //总数量
} LinkedList;
接下来是链表操作
1·、创建链表函数
//添加链表
LinkedListSingle *LinkedList_add(LinkedList **list_base_ptr,void *data)
{
LinkedListSingle *list_ptr=(LinkedListSingle *)malloc(sizeof(LinkedListSingle)); //创建节点
LinkedList *list_all_ptr;
list_ptr->next=NULL; //初始化节点信息 ,注意新节点的下一个节点信息是空的
list_ptr->data=data; //填充链表数据
if(*list_base_ptr==NULL) //首次创建链表
{
list_all_ptr= (LinkedList *)malloc(sizeof(LinkedList));
*list_base_ptr=list_all_ptr;
list_ptr->id=0; //自增ID序列号,方便查找
list_all_ptr->head=list_all_ptr->tail=list_ptr; //首次创建之后填充第一个节点的信息到链表头
list_all_ptr->length=1; //链表头数量
}
else
{
list_all_ptr=*list_base_ptr; //获得新增节点的上一接点的信息
list_ptr->id = list_all_ptr->tail->id+1; //自增ID序列号
list_all_ptr->tail->next = list_ptr; //更新新增节点的,上一接点的,下个节点的信息
list_all_ptr->tail=list_ptr; //更新链表尾部为当前节点
++list_all_ptr->length;
}
return list_ptr;
}
2、查找节点,更据自增序号查找
//根据节点id序列,查找节点数据
LinkedListSingle *LinkedList_find(LinkedList *list_base_ptr,uint16_t id)
{
LinkedListSingle *list_ptr=NULL;
uint16_t i;
if (list_base_ptr!=NULL)
{
list_ptr=list_base_ptr->head; //从链表头开始查找
for ( i= 0; i < list_base_ptr->length; i++)
{
if (list_ptr->id==id)
break;
list_ptr=list_ptr->next;
}
}
return list_ptr;
}
3、遍历链表,获得一个包含各个节点地址的数组,方便快速访问链表数据
//遍历链表,获得一个链表的数组,方便快速访问链表数据
LinkedListSingle** LinkedList_foreach(LinkedList *list_base_ptr)
{
LinkedListSingle *list_ptr=NULL;
LinkedListSingle **list_arr_ptr=NULL;
uint16_t i;
if (list_base_ptr!=NULL)
{
//二级指针动态分配一级指针内存
list_arr_ptr=(LinkedListSingle **)malloc(list_base_ptr->length*sizeof(LinkedListSingle *));
list_ptr=list_base_ptr->head;
for ( i= 0; i < list_base_ptr->length; i++)
{
list_arr_ptr[i]=list_ptr; //添加链表元素到链表头数组里面
list_ptr=list_ptr->next;
}
}
return list_arr_ptr;
}
4、删除节点
//根据id序列号删除节点信息,
void LinkedList_remove(LinkedList *list_base_ptr,uint16_t id)
{
LinkedListSingle *list_P_pre_ptr=NULL; //上一个节P(k-1)点信息
LinkedListSingle *list_P_ptr=NULL; //当前节P(k)点信息
uint16_t i;
if (list_base_ptr!=NULL)
{
list_P_ptr=list_base_ptr->head;
for ( i= 0; i < list_base_ptr->length; i++)
{
if (list_P_ptr->id==id) //查找到了要删除的节点
{
list_P_pre_ptr->next=list_P_ptr->next;
free(list_P_ptr);
--list_base_ptr->length;
break;
}
list_P_pre_ptr=list_P_ptr;
list_P_ptr=list_P_ptr->next;
}
}
}