链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链
接次序实现的。实际中链表的结构非常多样,以下情况组合起来就有8种链表结构:
- 单向、双向
- 带头、不带头
- 循环、非循环
本文学习总结最常用两种结构:
- 无头单向非循环链表:结构简单,一般不会单独用来存数据。
- 带头双向循环链表:结构复杂,一般用于单独存储数据。
无头单向非循环链表
定义无头单向非循环链表节点:
typedef struct SListNode
{
ElemType data;
struct SListNode *next;
}SListNode;
定义无头单向非循环链表结构:
typedef struct SList
{
SListNode *head; //结构体内为一个单链表节点类型的指针
}SList;
函数接口声明
void SListInit(SList *plist);
void SListPushBack(SList *plist,ElemType x);
static SListNode* _Buynode(ElemType x); //申请节点
void SListShow(SList *plist);
void SListPushFront(SList *plist, ElemType x);
void SListPopBack(SList *plist);
void SListDestroy(SList *plist);
void SListPopFront(SList *plist);
size_t SListLength(SList *plist);
void SListClear(SList *plist);
SListNode *SeqListFind(SList *plist,ElemType key);
void SListDeleteByVal(SList *plist, ElemType key);
void SListReverse(SList *plist);
void SListInsertByVal(SList *plist, ElemType x);
void SListSort(SList *plist);
函数接口实现
初始化链表:
void SListInit(SList *plist)
{
plist->head = NULL;
}
结点的空间申请:
static SListNode* _Buynode(ElemType x)
{
SListNode *s = (SListNode*)malloc(sizeof(SListNode));
assert(s!=NULL);
s->data = x;
s->next = NULL;
return s;
}
链表尾插: