单链表相关的博客:
C语言实现单链表面试题---基础篇
https://blog.csdn.net/qq_37941471/article/details/78033970
C语言实现单链表面试题---进阶
https://blog.csdn.net/qq_37941471/article/details/80437143
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。
链表中的数据是以结点来表示的,每个结点的构成:
元素(数据元素的映象)+ 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
代码实现如下:
1.头文件 list.h
#include <stdio.h>
#include <assert.h>
#include <windows.h>
#include <malloc.h>
typedef int DataType;
typedef struct ListNode
{
DataType data;
struct ListNode* next;
}ListNode;
ListNode* Buycode(DataType x);//创建节点
void PrintList(ListNode* plist);//打印链表
void PushBack(ListNode** pplist,DataType x);//在链表最后的位置插入一个节点
void PopBack(ListNode** pplist);//删除链表最后一个节点
void PushFront(ListNode** pplist,DataType x);//在链表最前面插入一个节点
void PopFront(ListNode** pplist);//删除链表最前面的一个节点
ListNode* Find(ListNode* plist,DataType x);//查找一个节点
void Insert(ListNode** pplist,ListNode* pos,DataType x);//在pos的前面插入一个节点
void Erase(ListNode** pplist,ListNode* pos);//删除pos节点
2.函数实现 list.c
#include "list.h"
ListNode* Buycode(DataType x)//创建节点
{
ListNode* Node = (ListNode *)malloc(sizeof(ListNode)) ;
Node->data = x ;
Node->next = NULL ;
return Node;
}
void PrintList(ListNode* plist)//打印链表
{
ListNode* cur = plist ;
while(cur)
{
printf("%d->",cur->data);
cur = cur->next ;
}
printf("NULL\n");
}
void PushBack(ListNode** pplist,DataType x)//在链表最后的位置插入一个节点
{
// 1 2 3 4
//1.链表为空
//2.一个
//3.多个
if(*pplist == NULL)
{
*pplist = Buycode(x) ;
}
else if((*pplist)->next == NULL)
{
(*pplist)->next = Buycode(x);
}
else
{
ListNode* cur = *pplist ;
while( cur->next )
{
cur = cur->next ;
}
cur->next = Buycode(x);
}
}
void PopBack(ListNode** pplist)//删除链表最后一个节点 0 1 2 3
{
//1.空链表
//2.一个节点
//3.多个节点
if(*pplist == NULL)
{
return;
}
else if((*pplist)->next == NULL)
{
free(*pplist);
*pplist = NULL;
}
else
{
ListNode* cur = *pplist;
ListNode* pos = *pplist;
while(cur->next)
{
pos = cur;
cur = cur->next ;
}
free(cur);
cur = NULL;
pos->next = NULL;
}
}
void PushFront(ListNode** pplist,DataType x)//在链表最前面插入一个节点 1 2 3 4(头插)
{/*
1.空链表
2.非空*/
if(*pplist == NULL)
{
*pplist = Buycode(x);
}
else
{
ListNode* tmp = Buycode(x);
tmp->next = *pplist;
*pplist = tmp;
}
}
void PopFront(ListNode** pplist)//删除链表最前面的一个节点1 2 3 4
{
/*1.空链表
2.一个节点
3.多个节点*/
if(*pplist == NULL)
{
return;
}
else if((*pplist)->next == NULL )
{
PopBack(pplist);
}
else
{
ListNode* next = (*pplist)->next ;
free(*pplist);
*pplist = next;
}
}
ListNode* Find(ListNode* plist,DataType x)//查找一个节点0 1 2 3 4
{
while(plist)
{
if(plist->data == x)
{
return plist;
}
plist = plist->next ;
}
return NULL;
}
//prev pos
void Insert(ListNode** pplist,ListNode* pos,DataType x)//在pos的前面插入一个节点0 1 3 4
{
assert(pplist&&pos);
/*1.如果pos是头结点,则是头插
2.pos是其他节点*/
if(pos == *pplist)
{
PushFront(pplist,x);
}
else
{
ListNode* tmp = NULL;
ListNode* prev = *pplist;
while(prev->next != pos)
{
prev = prev->next ;
}
tmp = Buycode(x);
prev->next = tmp;
tmp->next = pos;
}
}
void Erase(ListNode** pplist,ListNode* pos)//删除pos节点
{
assert(pplist&&pos);
/*1.头删
2.尾删
3.中间删1 2 3 4 删除3*/
if(pos == *pplist)
{
PopFront(pplist);
}
else if(pos->next == NULL)
{
PopBack(pplist);
}
else
{
ListNode* prev = *pplist ;
while(prev->next != pos)
{
prev = prev->next ;
}
prev->next = pos->next ;
free(pos);
pos = NULL;
}
}
3.测试函数 test.c
#include "list.h"
void test1()
{
ListNode* list = NULL;
//测试尾插
PushBack(&list,0);
PushBack(&list,1);
PushBack(&list,2);
PushBack(&list,3);
PushBack(&list,4);
PrintList(list);
//测试尾删
PopBack(&list);
PrintList(list);
PopBack(&list);
PopBack(&list);
PopBack(&list);
PopBack(&list);
PopBack(&list);
PrintList(list);
}
void test2()
{
ListNode* list = NULL;
ListNode* pos;
//测试头插
PushFront(&list,1);
PushFront(&list,2);
PushFront(&list,4);
PrintList(list);
//测试头删
PopFront(&list);
PrintList(list);
PopFront(&list);
PopFront(&list);
PopFront(&list);
PopFront(&list);
PopFront(&list);
PrintList(list);
}
void test3()
{
ListNode* list = NULL;
ListNode* pos;
PushFront(&list,0);
PushFront(&list,1);
PushFront(&list,2);
PushFront(&list,4);
PrintList(list);
//测试查找函数
pos = Find(list,2);
//测试在pos位置前面插入x
Insert(&list,pos,3);
PrintList(list);
//测试删除pos位置的节点
pos = Find(list,4);
Erase(&list,pos);
PrintList(list);//头删
pos = Find(list,0);
Erase(&list,pos);
PrintList(list);//尾删
pos = Find(list,2);
Erase(&list,pos);
PrintList(list);//中间删除
}
int main()
{
test3();
return 0;
}
test1()函数的运行结果:
test2()函数的运行结果:
test3()函数的运行结果: