目录
一、概念与结构
1、节点
结点的组成主要有:当前结点要保存的数据和保存下一个节点的地址(指针变量)
图中指针变量plist保存的是第一个结点的地址,我们称plist此时“指向”第一个结点。
链表中每个结点都是独立申请的(如果需要插入数据时才去申请一块结点的空间),我们需 要通过指针变量来保存下一个结点位置才能从当前结点找到下一个结点。
2、链表的性质
【链表机构在逻辑上是连续的,在物理结构上不一定连续。
【结点一般是从堆上申请的。
【从堆上申请来的空间,是按照一定策略分配出来的,每次申请的空间可能连续,可能不连续。
二、实现单链表
1、创立文件
2、定义链表的结构
【SList.h】
//定义链表(结点)的位置
typedef int SLTDataType;
typedef struct SListNode
{
SLTDataType data;
struct SListNode* next;
}SLTNode;
void SLTPrint(SLTNode* phead);
3、打印函数
【SList.h】
//打印函数
void SLTPrint(SLTNode* phead);
【SList.c】
//打印函数
void SLTPrint(SLTNode* phead)
{
SLTNode* pcur = phead;
while (pcur)
{
printf("%d->", pcur->data);
pcur = pcur->next;
}
printf("NULL\n");
}
【test.c】
//创建一个链表,并且打印链表
void createSList()
{
SLTNode* node1 = (SLTNode*)malloc(sizeof(SLTNode));
node1->data = 1;
SLTNode* node2 = (SLTNode*)malloc(sizeof(SLTNode));
node1->data = 2;
SLTNode* node3 = (SLTNode*)malloc(sizeof(SLTNode));
node1->data = 3;
SLTNode* node4 = (SLTNode*)malloc(sizeof(SLTNode));
node1->data = 4;
node1->next = node2;
node2->next = node3;
node3->next = node4;
node4->next = NULL;
//第一个结点的地址作为参数传递过去
SLTNode* plist = node1;
SLTPrint(node1);
}
4、判断插入时,空间是否足够
【SList.c】
//判断插入数据时,空间是否足够
SLTNode* SLTBuyNode(SLTDataType x)
{
SLTNode* node = (SLTNode*)malloc(sizeof(SLTNode));
if (node == NULL)
{
perror("malloc fail!");
exit(1);
}
node->data = x;
node->next = NULL;
return node;
}
5、尾插
【SList.h】
//尾插
void SLTPushBack(SLTNode** pphead,SLTDataType x);
【SList.c】
//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{
assert(pphead);
//形参:pphead --> 实参:&plist
//*pphead 解引用 --> plist
//申请新结点
SLTNode* newnode = SLTBuyNode(x); //判断是否有足够空间
if (*pphead == NULL)
{
*pphead = newnode;
}
else
{
//尾节点 --> 新结点
//找尾节点
SLTNode* ptail = *pphead;
while (ptail->next)
{
ptail = ptail->next;
}
//ptail --> newnode
ptail->next = newnode;
}
}
【test.c】
void SListTest01()
{
SLTNode* plist = NULL;
SLTPushBack(&plist, 1);
SLTPrint(plist); //1->NULL
SLTPushBack(&plist, 2);
SLTPrint(plist); //1->2->NULL
SLTPushBack(&plist, 3);
SLTPrint(plist); //1->2->3->NULL
SLTPushBack(&plist, 4);
SLTPrint(plist); //1->2->3->4->NULL
}
【运行结果】
6、头插
【SList.h】
//头插
void SLTPush