链表
概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链
接次序实现的 。
实际中链表的结构非常多样,以下情况组合起来就有8种链表结构:
- 单向、双向
- 带头、不带头
- 循环、非循环
但是生活中最常用的则是无头单向非循环链表和带头循环双向链表
1、无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。
2、带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了。
链表功能的实现
1、无头单向非循环链表
typedef int SLTDataType;
//链表结构体
typedef struct SListNode
{
SLTDataType data; // val
struct SListNode* next;
}SListNode;
// 动态申请一个节点
SListNode* BuySListNode(SLTDateType x);
//输出(打印)
void SListPrint(SListNode* pList);
//尾插
void SListPushBack(SListNode** ppList, SLTDataType x);
//头插
void SListPushFront(SListNode** pList, SLTDataType x);
//尾删
void SListPopBack(SListNode** ppList);
//头删
void SListPopFront(SListNode** pList);
// 单链表查找
SListNode* SListFind(SListNode* plist, SLTDataType x);
// 单链表在pos位置之后插入
void SListInsertAfter(SListNode* pos, SLTDataType x);
// 单链表删除pos位置之后的值
void SListEraseAfter(SListNode* pos);
//单链表的销毁
void SListDestory(SListNode** pplist);
//打印
void SListPrint(SListNode* pList)
{
SListNode* cur = pList;
while (cur != NULL)
{
printf("%d->", cur->data);
cur = cur->next;
}
printf("NULL\n");
}
//动态申请一个节点
SListNode* BuySListNode(SLTDataType x)
{
SListNode* newNode = (SListNode*)malloc(sizeof(SListNode));
newNode->data = x;
newNode->next = NULL;
return newNode;
}
//尾插
void SListP