1.链表概念
链表是一种物理存储结构上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现。
2.链表分类
(1)单向、双向
(2)带头、不带头
(3)循环、非循环
这些组合一共有8种链表类型,但在实际中最常用的还是两种结构;
(1)无头单向非循环链表
特点:结构简单,一般不会单独用来存数据,更多的是作为其他数据结构的子结构,如哈希桶,图的邻接表等。
(2)带头双向循环链表
特点:结构最复杂,一般用在单独存储数据,实际中使用的链表数据结构都是带头双向循环链表。
3.接口函数实现
(1)初始化链表
代码如下(示例):
void listInit(list* lst)
{
if (lst == NULL)
return;
lst->_head = NULL;
}
(2)创建节点
代码如下(示例):
listNode* creatNode(LDataType val)
{
struct listNode* node = (listNode*)malloc(sizeof(listNode));
node->_data = val;
node->_next = NULL;
return node;
}
(3)尾插一个元素
代码如下(示例):
void listPushBack(list* lst,LDataType val)
{
if (lst == NULL)
return;
//第一种情况:空链表插入第一个数据
if (lst->_head == NULL)
{
//创建节点
lst->_head = creatNode(val);
}
else
{
//遍历找到最后一个节点
listNode* tail = lst->_head;
while (tail->_next != NULL){
tail = tail->_next;
}
tail->_next = creatNode(val);
}
}
(4)尾删一个元素
代码如下(示例):
void listPopBack(list* lst)
{
if (lst == NULL||lst->_head==NULL)
return;
struct listNode* tail = lst->_head;
struct listNode* prev = NULL;
//遍历找到最后一个节点
while (tail->_next != NULL)
{
prev = tail;
tail = tail->_next;
}
//删除节点
free(tail);
//修改指向
if (prev == NULL)
lst->_head = NULL;
else
prev->_next = NULL;
}
(5)头插一个元素
代码如下(示例):
void listPushFront(list* lst, LDataType val)
{
if (lst == NULL)
return;
//空的链表,插入第一个数据
if (lst->_head == NULL)
lst->_head = creatNode(val);
else
{
listNode* node = creatNode(val);
listNode* next = lst->_head;
lst->_head = node;
node->_next = next;
}
}
(6)头删一个元素
代码如下(示例):
void listPopFront(list* lst)
{
if (lst == NULL||lst->_head==NULL)
return;
struct listNode* next = lst->_head->_next;
//释放头结点
free(lst->_head);
lst->_head = next;
}
(7)中间位置插入一个元素
代码如下(示例):
void listInsertAfter(listNode* cur, LDataType val)
{
listNode* node = creatNode(val);
listNode* next = cur->_next;
cur->_next = node;
node->_next = next;
}
(8)中间位置删除一个元素
代码如下(示例):
void listEraseAfter(listNode* cur)
{
listNode* next = cur->_next;
if (next == NULL)
return;
struct listNode* nextnext = next->_next;
free(next);
cur->_next = nextnext;
}
(9)中间节点数据的查找
代码如下(示例):
listNode* listFind(list* lst, LDataType val)
{
if (lst == NULL || lst->_head == NULL)
return NULL;
//从第一节点开始遍历,直到找到val的值,返回此值得指针
struct listNode* cur = lst->_head;
while (cur){
if (cur->_data == val)
return cur;
cur = cur->_next;
}
return NULL;
}
(10)链表的Destroy
代码如下(示例):
void listDestroy(list* lst)
{
if (lst == NULL || lst->_head)
return;
struct listNode* cur = lst->_head;
while (cur)
{
listNode* next = cur->_next;
free(cur);
cur = next;
}
lst->_head = NULL;
}