相关博客链接:
C语言实现 单向链表
https://blog.youkuaiyun.com/qq_37941471/article/details/72961495
C语言实现单链表面试题—基础篇
https://blog.youkuaiyun.com/qq_37941471/article/details/78033970
C语言实现单链表面试题—进阶
https://blog.youkuaiyun.com/qq_37941471/article/details/80437143
代码:
List.h List.c test.c
- List.h :
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <windows.h>
#include <assert.h>
typedef int DataType;
typedef struct ListNode
{
DataType data;//节点存放的数据
struct ListNode* next;//下一个节点
}ListNode;
ListNode* BuyNode(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);//查找x
void Insert(ListNode **pplist,ListNode* pos,DataType x);//在pos位置前面插入节点
void Erase(ListNode **pplist,ListNode *pos);//删除pos节点
void PrintTailToHead(ListNode *plist);//2.从尾到头打印单链表
void EraseNonTail(ListNode* pos);//3.删除一个无头单链表的非尾节点
void InsertNonHead(ListNode* pos,DataType x);//4.在无头单链表的一个节点前插入一个节点
ListNode* JosepRing(ListNode* list,DataType k);//5.单链表实现约瑟夫环
void Reverse(ListNode** pplist);//6.翻转/逆置链表
void SortList(ListNode* list);//7.单链表排序(冒泡排序)
ListNode* Merge(ListNode* list1,ListNode* list2);//8.合并两个有序单链表,合并后依然有序
ListNode* FindMidNode(ListNode* plist);//9.查找链表的中间节点,要求只能遍历一次
void FindKNode(ListNode* plist,int k);//10.查找单链表的倒数第k个节点,要求只能遍历一次
ListNode* IsCycle(ListNode* plist);//11.判断链表是否带环?
ListNode* GetEntry(ListNode* plist, ListNode* MeetNode);//若带环,求其入口点
int GetCycle_Length(ListNode* MeetNode);//若带环,求环的长度
int IsCross_NoCycle(ListNode* plist1,ListNode* plist2);//12.判断两个链表是否相交?(假设链表不带环)
ListNode* GetCrossNode(ListNode* plist1, ListNode* plist2);//若相交,求交点
ListNode* IsCross_Cycle(ListNode* plist1,ListNode* plist2);//13.判断两个链表是否相交?若相交,求交点。(假设链表可能带环)
- List.c :
#include "List.h"
ListNode* BuyNode(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)//尾插
{
assert(pplist);
//1. 链表为空
//2. 一个节点
//3. 多个节点
if( *pplist == NULL )
{
*pplist = BuyNode(x);
}
else if( (*pplist)->next == NULL )
{
(*pplist)->next = BuyNode(x);
}
else //多节点
{
ListNode* cur = *pplist;
while ( cur->next ) //终止条件(找最后一个节点):cur->next == NULL;所以继续条件恰好相反
{
cur = cur->next ;
}
cur->next = BuyNode(x);
}
}
void PopBack(ListNode **pplist)//尾删
{
assert(pplist);
//1. 链表为空
//2. 一个节点
//3. 多个节点
if( *pplist == NULL )
return;
else if( (*pplist)->next == NULL )
{
free(*pplist);//malloc free()
*pplist = NULL;
}
else//多节点
{
ListNode* prev = *pplist;
ListNode* cur = *pplist;
while( cur->next )
{
prev = cur;
cur = cur->next ;
}
free(cur);
cur = NULL;
prev->next = NULL;
}
}
void PushFront(ListNode **pplist,DataType x)//头插
{
assert(pplist);
//1. 链表为空
//2. 非空
if( *pplist == NULL )
{
*pplist = BuyNode(x);
}
else //非空
{
ListNode* Node = BuyNode(x);
Node->next = *pplist;
*pplist = Node;
}
}
void PopFront(ListNode **pplist)//头删
{
assert(pplist);
//1. 链表为空
//2. 一个节点
//3. 多节点
if( *pplist == NULL )
return;
else if ( (*pplist)->next == NULL )
{
free(*pplist);
*pplist = NULL;
}
else//多节点
{
ListNode* tmp = *pplist;
ListNode* Next = (*pplist)->next ;
*pplist = Next;
free(tmp);
}
}
ListNode* Find(ListNode *plist,DataType x)//查找x
{
assert(plist);
while( plist )
{
if( plist->data == x )
return plist;
plist = plist->next ;
}
return NULL;
}
void Insert(ListNode