目录
1.1 单链表的概念
链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的,单链表是一种链式存取的数据结构,链表中的数据是以结点来表示的,每个结点由元素和指针构成。
链表通过不连续的储存方式,自适应内存大小,以及指针的灵活使用,巧妙的简化了上述的内容。
链表的基本思维是,利用结构体的设置,额外开辟出一份内存空间去作指针,它总是指向下一个结点,一个个结点通过NEXT指针相互串联,就形成了链表。
1.2 单链表的结构
以结点的序列表示的线性表称作线性链表,也就是单链表,单链表是链式存取的结构。对于链表的每一个结点,我们使用结构体进行设计,其主要内容有
其中,DATA数据元素,可以为你想要储存的任何数据格式,NEXT为一个指针,其代表了一个可以指向的区域,通常是用来指向下一个结点,链表的尾部NEXT指向NULL(空),因为尾部没有任何可以指向的空间了
1.3 本期链表的结构实现:无头单向非循环链表
1. 无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。
2. 单链表的实现
SList.c | 单链表函数实现 |
SList.h | 创建单链表,单链表申明 |
Test.c | 测试单链表 |
2.1 单链表定义
typedef int SLTDateType;//便于修改数据类型
typedef struct SList
{
SLTDateType Node;//数据
struct SList* next;//结点
}SList;
2.2 动态申请内存
注意事项:
1.动态开辟内存有可能开辟失败
SList* BuySListNode(SLTDateType x)//动态申请一个节点
{
SList* NewNode = (SList*)malloc(sizeof(SList));//动态开辟内存空间
assert(NewNode);//有可能开辟失败
NewNode->Node = x;
NewNode->next = NULL;//指针初始化
return NewNode;
}
2.3 单链表尾插
注意事项:
1.需考虑两种情况:此时单链表上存在结点、此时单链表上不存在结点
2.如果此时需要修改plist,我们传一级指针是否可行?
一级指针传参用一级指针接收,传过来的是形参,接收的只是一级指针的值,我们修改一级指针无法改变plist,所以我们需要传递二级指针pplist来改变一级指针plist
3.遍历找到最后一个结点,使用尾结点连接新开辟的空间
void SListPushBack(SList** pplist, SLTDateType x)//尾插单链表
{
assert(pplist);
SList* NewNode = BuySListNode(x);//开辟新空间
//考虑此时头结点没有数据
if (*pplist == NULL)
{
*pplist = NewNode;
}
else
{
//考虑已经有结点,尾插数据
SList* tail = *pplist;
while(tail->next != NULL)
{
tail = tail->next;//找到尾
}
tail->next = NewNode;//尾插
}
}
2.4 单链表的尾删
注意事项:
1.要改变plist,就得传二级指针
2.此时有一个以上结点