数据类型的定义
typedef int DataType;
typedef struct ListNode
{
DataType data;
struct ListNode *next;
} ListNode;
链表的初始化和销毁
链表的初始化—–>构造一条空链表
链表的销毁—–>销毁每个结点
//初始化
void ListInit(ListNode **pFirst)
{
*pFirst = NULL;
}
//销毁
void ListDestory(ListNode **pFirst)
{
ListNode *cur = NULL;
ListNode *del = NULL;
assert(*pFirst);
cur = *pFirst;
while(cur->next != NULL)
{
del = cur;
cur = cur->next;
free(del);
}
free(cur);
}
打印链表
void ListPrint(ListNode **pFirst)
{
ListNode *cur = NULL;
assert(*pFirst != NULL);
cur = *pFirst;
while(cur != NULL)
{
printf("%d ",cur->data);
cur = cur->next;
}
printf("\n");
}
查找
按值查找,如果找到了返回第一个找到的结点指针,如果没找到,返回NULL。代码如下:
ListNode *ListFind(ListNode **pFirst, DataType data)
{
ListNode *cur = NULL;
assert(*pFirst != NULL);
cur = *pFirst;
while(cur != NULL)
{
if(cur->data == data)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
增加数据
在增加数据前,需要一个函数来创建一个新结点,函数返回新结点的地址,通过改变链表中结点的next指向来将新结点加入到链表中。代码如下:
ListNode *CreateNode(DataType data)
{
ListNode *NewNode = (ListNode *)malloc(sizeof(DataType));
NewNode->data = data;
NewNode->next = NULL;
return NewNode;
}
尾插
代码如下:
void ListPushBack(ListNode **pFirst, DataType data)
{
ListNode *cur = NULL;
//如果链表为空
if(*pFirst == NULL)
{
*pFirst = CreateNode(data);
return ;
}
//链表不为空
cur = *pFirst;
while(cur->next != NULL)
{
cur = cur->next;
}
cur->next = CreateNode(data);
}
头插
代码如下:
void ListPushFront(ListNode **pFirst, DataType data)
{
ListNode *cur = NULL;
//如果链表为空
if(*pFirst == NULL)
{
*pFirst = CreateNode(data);
return ;
}
//链表不为空
cur = *pFirst;
*pFirst = CreateNode(data);
(*pFirst)->next = cur;
}
指定位置插入(插入到结点前)
代码如下:
void ListInsert(ListNode **pFirst, ListNode *pos, DataType data)
{
ListNode *cur = NULL;
ListNode *NewNode = NULL;
assert(*pFirst != NULL);
if(pos == NULL)
return ;
//如果在第一个元素位置前插入,调用头插函数
if(pos == *pFirst)
{
ListPushFront(pFirst, data);
}
cur = *pFirst;
NewNode = CreateNode(data);
while(cur->next != pos)
{
cur = cur->next;
}
cur->next = NewNode;
NewNode->next = pos;
}
删除数据
尾删
代码如下:
void ListPopBack(ListNode **pFirst)
{
ListNode *cur = NULL;
ListNode *del = NULL;
assert(*pFirst != NULL);
//如果链表只有一个元素
if((*pFirst)->next == NULL)
*pFirst = NULL;
//如果链表有多个元素
cur = *pFirst;
while(cur->next->next != NULL)
{
cur = cur->next;
}
del = cur->next->next;
cur->next = NULL;
free(del);
}
头删
代码如下:
void ListPopFront(ListNode **pFirst)
{
ListNode *del = NULL;
assert(*pFirst != NULL);
//如果链表只有一个元素
if((*pFirst)->next == NULL)
{
*pFirst = NULL;
}
//如果链表有多个元素
del = *pFirst;
*pFirst = (*pFirst)->next;
//free(del);
}
删除给定结点
代码如下:
void ListErase(ListNode **pFirst, ListNode *pos)
{
ListNode *del = NULL;
ListNode *cur = NULL;
assert(*pFirst != NULL);
//如果给定结点不存在
if(pos == NULL)
return ;
//如果给定结点是第一个元素 调用头删函数
if(pos == *pFirst)
{
ListPopFront(pFirst);
return ;
}
//如果给定结点是最后一个 调用尾删函数
else if(pos->next == NULL)
{
ListPopBack(pFirst);
return ;
}
//如果给定结点是除首尾外元素
cur = *pFirst;
while(cur->next != pos)
{
cur = cur->next;
}
cur->next = cur->next->next;
//free(pos);
}
删除指定元素
分为两种情况:
1、如果要删除元素是第一个元素,就调用头删函数;
2、如果要删除元素不是第一个元素,遍历该链表,找到第一个等于要删除元素的结点,将该结点的前一个结点的next指向该结点的下一个结点,即删除了该元素。
代码如下:
void ListRemove(ListNode **pFirst, DataType data)
{
ListNode *cur = NULL;
ListNode *del = NULL;
assert(*pFirst != NULL);
//如果删除的元素为第一个元素
if((*pFirst)->data == data)
{
ListPopFront(pFirst);
return ;
}
cur = *pFirst;
while(cur != NULL)
{
if(cur->next->data == data)
{
del = cur->next;
cur->next = cur->next->next;
return ;
}
cur = cur->next;
}
}
删除所有指定元素
void ListRemoveAll(ListNode **pFirst, DataType data)
{
ListNode *cur = NULL;
assert(*pFirst != NULL);
cur = *pFirst;
while(cur != NULL)
{
if((*pFirst)->data == data)
{
*pFirst = (*pFirst)->next;
}
else if(cur->next->data == data)
{
cur->next = cur->next->next;
}
cur = cur->next;
}
}
上述内容均为学习过程中的总结,如有不足之处,请指正