1、基本概念:
链表:链表一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
链表总共有8种结构:
1、无头单向非循环 2、无头单向循环 3、带头单项循环 4、带头单项非循环
5、无头双向非循环 6、无头双向循环 7、带头双向非循环 8、带头双向循环
实际中最常用的就是:
无头单项非循环链表:
带头双向循环链表:
2、代码实现 单向无头非循环链表:
2.1准备工作:
首先对头文件的引用和创建一个结构体。这个结构体就是链表的节点,一个节点包含数据项和指针项,指针项中存储的是下一个节点的地址。(假设存储的数据是int类型)
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef int DataType;
//无头单向非循环
typedef struct SListNode
{
DataType data;
struct SListNode* next;
}SLNode;
SLNode* phead=NULL;//创建一个空链表
2.2链表的基本操作
2.2.1尾插函数 (在链表尾部插入数据)
只要是插入数据就得重新malloc一个新节点,数据项赋值为你想要的值,指针项赋值为空。所以先封装一个生成新节点的函数。
SLNode* BuyNewNode(DataType x)
{
SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
if (newnode == NULL)
{
printf("malloc fail\n");
exit(-1);
}
else
{
newnode->data = x;
newnode->next = NULL;
}
return newnode;
}
尾插函数:新节点创建完成后。要找到链表的尾将其插入。分两种情况,链表为空和链表非空的情况。非空要找到尾节点再链接。
void SListPushBack(SLNode** pphead, DataType x)
{
SLNode* newnode = BuyNewNode(x);
//找尾
//1.链表为空的时候
if (*pphead == NULL)
{
*pphead = newnode;
}
//2.链表为非空
else
{
SLNode* tail = *pphead;
while (tail->next != NULL)
{
tail = tail->next;
}
tail->next = newnode;
}
}
这里为什么要传二级指针(**pphead):因为phead是一个指针类型存的是第一个节点的地址,如果链表为空的时候,尾插时是要改变phead的值,所以要传phead的地址,地址的地址就要用二级指针。
2.2.2头插函数(在链表最前面插入数据)
创建一个新节点,如果链表为空则直接插入。
链表非空:
红色箭头为else的链接过程。