在嵌入式开发过程中,使用单链表可以很方便的解决一些问题,如下代码可在单片机程序中使用。
头文件代码
#ifndef _LINKLIST_H_
#define _LINKLIST_H_
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
/* 定义结点数据域类型 */
typedef int ElemType;
/** @struct LNode
* @brief 链表结点
*
*/
typedef struct __LNode
{
ElemType data;
struct __LNode *next;
}LNode, *LinkList;
/***************************API*************************/
void CreateList_L(LinkList *L);
uint16_t GetLength_L(LinkList *L);
bool ListAppend_L(LinkList *L, ElemType e);
bool GetElem_L(LinkList *L, uint16_t i, ElemType *e);
bool ListInsert_L(LinkList *L, uint16_t i, ElemType e);
bool ListDelete_L(LinkList *L, uint16_t i, ElemType *e);
#endif /*_LINKLIST_H_*/
源文件代码
#include "LinkList.h"
/*==================================================================
* Function : CreateList_L
* Description : 创建带头结点的单链表(头结点不存储数据)
* Input Para :
* Output Para :
* Return Value :
==================================================================*/
void CreateList_L(LinkList *L)
{
/* 创建一个带头结点的单链表 */
(*L) = (LinkList)malloc(sizeof(LNode));
(*L)->next = NULL;
}
/*==================================================================
* Function : GetElem_L
* Description : L为带头结点的单链表的头指针
* Input Para :
* Output Para :
* Return Value :
==================================================================*/
bool GetElem_L(LinkList *L, uint16_t i, ElemType *e)
{
LinkList p = NULL;
uint16_t index = 0;
p = (*L)->next; /* p指向第一个结点 */
while (p && (index < i)) /* 顺指针向后查找 */
{
p = p->next;
index++;
}
if (!p || (index > i)) /* 第i个元素不存在 */
{
return false;
}
*e = p->data; /* 取第i个元素 */
return true;
}
/*==================================================================
* Function : GetLength_L
* Description :
* Input Para :
* Output Para :
* Return Value :
==================================================================*/
uint16_t GetLength_L(LinkList *L)
{
LinkList p = NULL;
uint16_t index = 0;
p = (*L)->next; /* p指向第一个结点 */
while (p)
{
p = p->next;
index++;
}
return index;
}
/*==================================================================
* Function : ListInsert_L
* Description : 在带头结点的单链表L中第i个位置之前插入元素e
* Input Para :
* Output Para :
* Return Value :
==================================================================*/
bool ListInsert_L(LinkList *L, uint16_t i, ElemType e)
{
LinkList p = NULL, s = NULL;
uint16_t index = 0;
p = (*L);
while (p && (index < i)) /* 寻找第i-1个结点 */
{
p = p->next;
index++;
}
if (!p || (index > i)) /* i小于1或者大于表长加1 */
{
return false;
}
s = (LinkList)malloc(sizeof(LNode)); /* 生成新结点 */
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
/*==================================================================
* Function : ListAppend_L
* Description : 在链表尾部追加元素
* Input Para :
* Output Para :
* Return Value :
==================================================================*/
bool ListAppend_L(LinkList *L, ElemType e)
{
uint16_t usTail = 0;
usTail = GetLength_L(L);
ListInsert_L(L, usTail, e);
return true;
}
/*==================================================================
* Function : ListDelete_L
* Description : 在带头结点的单链表L中,删除第i个元素,并由e返回其值
* Input Para :
* Output Para :
* Return Value :
==================================================================*/
bool ListDelete_L(LinkList *L, uint16_t i, ElemType *e)
{
LinkList p = NULL, q = NULL;
uint16_t index = 0;
p = (*L);
while (p->next && (index < i)) /* 寻找第i个结点 */
{
p = p->next;
index++;
}
if (!(p->next) || (index > i)) /* 删除位置不合理 */
{
return false;
}
/* 删除并释放结点 */
q = p->next;
p->next = q->next;
*e = q->data;
free(q);
return true;
}
#if 0
/*==================================================================
* Function : LinkListTest
* Description : 链表的基本操作用例
* Input Para :
* Output Para :
* Return Value :
==================================================================*/
void LinkListTest(void)
{
ElemType data = 0;
LinkList head = NULL; /* 定义头结点指针 */
CreateList_L(&head); /* 初始化带头结点的链表 */
/* 第i个位置,插入链表元素 */
ListInsert_L(&head, 0, 1);
ListInsert_L(&head, 1, 2);
ListInsert_L(&head, 2, 3);
/* 查询链表长度 */
printf("LinkList length: %d\r\n", GetLength_L(&head));
/* 追加链表元素 */
ListAppend_L(&head, 4);
/* 删除1位置的元素 */
if (ListDelete_L(&head, 1, &delData))
{
printf("Del:%d\r\n", delData);
}
/* 获取链表第i个位置元素 */
if (GetElem_L(&head, 1, &data))
{
printf("%d\r\n", data);
}
else
{
printf("index error!\r\n");
}
}
#endif