在这里,我把所有关于单链表的基本操作,以及面试单链表时经常遇到的操作全部实现了一遍(正文分两大部分,第一部分为单链表基本操作,第二部分为面试题)相信大家在面试时只要是问道关于单链表的题目,肯定能派上用场哦!好了,废话不多说,直接上干货。
#include<assert.h>
#define NULL 0
#include<malloc.h>
#include<stdio.h>
typedef int DataType;
typedef struct Node
{
struct Node*next;
struct Node*random;
DataType data;
}Node, *pNode;
//****************************//
//***单链表基本操作****//
//****************************//
void InitList(pNode *pHead);//初始化
pNode BuyNode(DataType data);//构造一个节点
void PushBack(pNode *pHead, DataType data);//尾插
void PopBack(pNode *pHead);//尾删
void PrintList(pNode pHead);//打印单链表
void PushFront(pNode *pHead, DataType data);//头插
void PopFront(pNode *pHead);//头删
pNode Find(pNode pHead, DataType data);//查找
void Insert(pNode pos, DataType data);//任意位置插入结点
void Delete(pNode *pHead, pNode pos);//任意位置删除结点
void Remove(pNode* pHead, DataType data); //删除为date节点
void RemoveAll(pNode* pHead, DataType data);//删除所有为data的结点
size_t size(pNode pHead); //求大小
pNode Front(pNode pHead); //返回尾节点
pNode Back(pNode pHead); //返回头节点
int Empty(pNode pHead); //判空
void InitList(pNode* pHead) //初始化链表
{
assert(pHead);
*pHead = NULL;
}
pNode BuyNode(DataType data) //构建一个结点
{
pNode pTemp = (pNode)malloc(sizeof(Node));
if (pTemp)
{
pTemp->data = data;
pTemp->next = NULL;
}
return pTemp;
}
void PushBack(pNode *pHead, DataType data)//尾插,空链表和多个结点
{
assert(pHead);
if (NULL == *pHead)
{
*pHead = BuyNode(data);
}
else
{
pNode pCur = *pHead;
while (pCur->next)
{
pCur = pCur->next;
}
pCur->next = BuyNode(data);
}
}
void PopBack(pNode *pHead)//尾删,不存在、一个结点、多个结点
{
assert(pHead);
if (NULL == *pHead)
{
return;
}
else if (NULL == (*pHead)->next)
{
free(*pHead);
*pHead = NULL;
}
else
{
pNode pCur = *pHead;
pNode pPre = pCur;
while (pCur->next)
{
pPre = pCur;
pCur = pCur->next;
}
free(pCur);
pPre->next = NULL;
}
}
void PrintList(pNode pHead) //打印单链表
{
pNode pCur = pHead;
while (pCur)
{
printf("%d->", pCur->data);
pCur = pCur->next;
}
printf("NULL\n");
}
void PushFront(pNode *pHead, DataType data) //头插
{
assert(pHead);
pNode pNewNode = BuyNode(data);
if (pNewNode)
{
pNewNode->next = *pHead;
*pHead = pNewNode;
}
}
void PopFront(pNode *pHead) //头删
{
pNode ps = NULL;
assert(pHead);
if (*pHead == NULL)
return;
else
{
ps = *pHead;
*pHead = (*pHead)->next;
free(ps);
}
}
pNode Find(pNode pHead, DataType data) //查找一个节点
{
assert(pHead);
pNode PcurNode = pHead;
while (PcurNode)
{
if (PcurNode->data == data)
{
return PcurNode;
}
PcurNode = PcurNode->next;
}
return NULL;
}
void Insert(pNode pos, DataType data) //任意位置插入节点
{
pNode pNewNode = NULL;
if (NULL == pos)
return;
pNewNode = BuyNode(data);
pNewNode->next = pos->next;
pos->next = pNewNode;
}
void Delete(pNode *pHead, pNode pos) //任意位置删除节点
{
assert(*pHead);
if (NULL == pHead&&NULL == pos)
return;
if (pos = *pHead)
{
*pHead = pos->next;
free(pos);
}
else
{
pNode pPre = *pHead;
while (pPre->next != pos)
{
pPre = pPre->next;
}
pPre->next = pos->next;
free(pos);
}
}
void Remove(pNode* pHead, DataType data) //删除为data的结点
{
assert(pHead);
Delete(pHead, Find(*pHead, data));
}
void RemoveAll(pNode* pHead, DataType data) //删除所有为data的结点
{
assert(pHead);
pNode pCurNode = NULL;
pNode pPreNode = NULL;
pPreNode = *pHead;
pCurNode = pPreNode->next;
while (pCurNode)
{
if (pCurNode->data = data)
{
pPreNode->next = pCurNode->next;
free(pCurNode);
pCurNode = pPreNode->next;
}
else
{
pCurNode = pCurNode->next;
}
}
if ((*pHead)->data = data)
{
pCurNode = *pHead;
*pHead = (*pHead)->next;
free(pCurNode);
}
}
pNode Back(pNode pHead) //返回尾节点
{
assert(pHead);
pNode pCurNode = pHead;
if (NULL == pHead)
return NULL;
while (pCurNode->next)
pCurNode = pCurNode->next;
return pCurNode;
}
size_t size(pNode pHead) //求大小
{
pNode pCurNode = pHead;
size_t Count= 0;
while (pCurNode)
{
Count++;
pCurNode = pCurNode->next;
}
return Count;
}
//************链表常见面试题****************//
//************链表常见面试题****************//
//************链表常见面试题****************//
voidPrintListFromTailtoHeda(pNode pHead);//从尾到头打印单链表中的内容
void DelNotTailNode(pNode pos);//删除一个单链表的非尾节电,不能遍历单链表(腾讯笔试题)
void InsertNotHead(pNode pos, DataType data);//在无头单链表的一个非头结点前插入一个结点
pNode JosephCircle(pNode pHead, size_t M);//单链表实现约瑟夫环
pNode Reverse(pNode pHead);//逆制单链表(way1)
pNode Reverse_t(pNode pHead);//逆制单链表(way2)
void Bubble(pNode pHead);//单链表冒泡排序
pNode FindMidNode(pNode pHead);//查找单链表中间结点
pNode FindLastKNode(pNode pHead, size_t K);//查找单链表倒数第K个结点
void DeleteLastKNode(pNode* pHead, size_t K);//删除单链表倒数第K个结点
pNode Combine(pNode pHead1, pNode pHead2);//合并两个有序单链表
int IsTailCross(pNode pHead1, pNode pHead2);//判断两个单链表是否相交,
pNode GetTailCross(pNode pHead1, pNode pHead2);//求两单链表相交的交点
pNode HasCircle(pNode pHead);//判断单链表是否带环
size_t GetCircleLen(pNode pMeetNode);//若单链表带环,则获取环的长度
pNode GetEnterNode(pNode pHead, pNode pMeetNode);//获取带环单链表的入口点
intHasCircleWithCircle(pNode pHead1, pNode pHead2);//判断两个链表是否相交,若相交,求交点(假设链表可能带环)
pNode CopyComplexList(pNode pHead);//拷贝复杂链表
///
voidPrintListFromTailtoHeda(pNode pHead) //从尾到头打印单链表中的内容
{
if (pHead)
{
PrintListFromTailtoHeda(pHead->next);
printf("%d->", pHead->data);
}
}
void DelNotTailNode(pNode pos) //删除一个单链表的非尾节电,不能遍历单链表(腾讯笔试题)
{
pNode pDelNode = NULL;
if (NULL == pos || NULL == pos->next)
return;
else
{
pDelNode = pos->next;
pos->next = pDelNode->next;
pos->data = pDelNode->data;
free(pDelNode);
}
}
void InsertNotHead(pNode pos, DataType data) //在无头单链表的一个非头结点前插入一个结点
{
pNode pNewNode = NULL;
if (NULL == pos)
return;
pNewNode = BuyNode(pos->data);
if (pNewNode)
{
pNewNode->next = pos->next;
pos->next = pNewNode;
pos->data = data;
}
}
pNode JosephCircle(pNode pHead, size_t M) //单链表实现约瑟夫环
{
assert(pHead);
pNode pCurNode = pHead, pDelNode;
if (NULL == pHead)
return NULL;
while (pCurNode != pCurNode->next)
{ //1.报数
size_t Count = M;
while (--Count)
{
pCurNode= pCurNode->next;
}
//2.删除结点
pDelNode = pCurNode->next;
pCurNode->data = pDelNode->data;
pCurNode->next = pDelNode->next;
free(pDelNode);
}
return pCurNode;
}
pNode Reverse(pNode pHead) //逆制单链表(way1)
{
assert(pHead);
pNode pPre = NULL;
pNode pCur = NULL;
pNode pNext = NULL;
if (NULL == pHead&&NULL == pHead->next)
return pHead;
pPre = pHead;
pCur = pPre->next;
pNext = pCur->next;
while (pNext)
{
pCur->next = pPre;
pPre = pCur;
pCur = pNext;
pNext = pNext->next;
}
pCur->next = pPre;
pHead->next = NULL;
return pCur;
}
pNode Reverse_t(pNode pHead) //逆制单链表(way2)
{
assert(pHead);
pNode pPre = NULL;
pNode pCur = NULL;
pNode pNewHead = NULL;
if (NULL == pHead || NULL == pHead->next)
return pHead;
pPre = pHead;
pCur = pPre->next;
while (pCur)
{
pPre->next = pNewHead;
pNewHead = pPre;
pPre = pCur;
pCur = pCur->next;
}
pPre->next = pNewHead;
pNewHead = pPre;
return pNewHead;
}
void Bubble(pNode pHead) //单链表冒泡排序
{
assert(pHead);
pNode pPre = NULL;
pNode pCur = NULL;
pNode pTail = NULL;
int flag = 1;
if (NULL == pHead || NULL == pHead->next)
return;
while (pHead != pTail)
{
flag = 1;
pPre = pHead;
pCur = pPre->next;
while (pCur != pTail)
{
if (pPre->data > pCur->data)
{
DataType temp = pPre->data;
pPre->data = pCur->data;
pCur->data = temp;
flag= 0;
}
pPre = pCur;
pCur = pCur->next;
}
pTail = pPre;
if (flag)
return;
}
}
pNode FindMidNode(pNode pHead)
{
pNode pSlow = pHead;
pNode pFast = pHead;
while (pFast && pFast->next)//结点偶数个Fast先空,结点计数个,Fast->next先空;
{
pSlow = pSlow->next;
pFast = pFast->next->next;
}
return pSlow;//返回后一个结点,(结点为偶数个,则中间结点有两个)
}
pNode FindLastKNode(pNode pHead, size_t K)
{
assert(pHead);
pNode pFast = pHead;
pNode pSlow = pHead;
if (NULL == pHead || 0 == K)
return NULL;
while (K--)
{
if (NULL == pFast)
return NULL;
pFast = pFast->next;
}
while (pFast)
{
pFast = pFast->next;
pSlow = pSlow->next;
}
return pSlow;
}
pNode Combine(pNode pHead1, pNode pHead2)
{
pNode p1 = pHead1;
pNode p2 = pHead2;
pNode pNewHead = NULL;
pNode pTailNode = NULL;
if (NULL == pHead1)
return pHead2;
if (NULL == pHead2)
return pHead1;
if (p1->data < p2->data)
{
pNewHead = p1;
p1 = p1->next;
pTailNode = p1;
}
else
{
pNewHead = p2;
p2 = p2->next;
pTailNode = p2;
}
while (p1&&p2)
{
if (p1->data < p2->data)
{
pTailNode->next = p1;
p1 = p1->next;
}
else
{
pTailNode->next = p2;
p2 = p2->next;
}
pTailNode = pTailNode->next;
}
if (p1)
pTailNode->next = p1;
if (p2)
pTailNode->next = p2;
return pNewHead;
}
/
int IsTailCross(pNode pHead1, pNode pHead2)
{
pNode pTailNode1 = pHead1;
pNode pTailNode2 = pHead2;
if (NULL == pHead1 || NULL == pHead2)
return 0;
while (pTailNode1->next)
{
pTailNode1 = pTailNode1->next;
}
while (pTailNode2->next)
{
pTailNode2 = pTailNode2->next;
}
if (pTailNode1 == pTailNode2)
return 1;
return 0;
}
/
pNode GetTailCross(pNode pHead1, pNode pHead2)
{
size_t Count1 = 0;
size_t Count2 = 0;
int Gap = 0;
pNode pL1 = pHead1;
pNode pL2 = pHead2;
if (0==(IsTailCross(pHead1, pHead2)))
return NULL;
Count1 = size(pHead1);
Count2 = size(pHead2);
Gap = Count1 - Count2;
if (Gap > 0)
{
while (Gap--)
pL1=pL1->next;
}
else
{
while (Gap++)
pL2 = pL2->next;
}
while (pL1 != pL2)
{
pL1 = pL1->next;
pL2 = pL2->next;
}
return pL1;
}
/
pNode HasCircle(pNode pHead)
{
assert(pHead);
pNode pFast = pHead;
pNode pSlow = pHead;
while (pFast &&pFast->next)
{
pFast = pFast->next->next;
pSlow = pSlow->next;
if (pFast == pSlow)
return pFast;
}
return NULL;
}
size_t GetCircleLen(pNode pMeetNode)
{
pNode pCurNode = pMeetNode;
size_t Count = 1;
if (NULL == pMeetNode)
return 0;
while (pCurNode->next != pMeetNode)
{
Count++;
pCurNode = pCurNode->next;
}
return Count;
}
pNode GetEnterNode(pNode pHead, pNode pMeetNode)
{
pNode pM = pHead;
pNode pN = pMeetNode;
if (NULL == pHead || NULL == pMeetNode)
return NULL;
while (pM != pN)
{
pM = pM->next;
pN =pN->next;
}
return pM;
}
intHasCircleWithCircle(pNode pHead1, pNode pHead2)
{
pNode pL1 = pHead1;
pNode pL2 = pHead2;
pNode pMeetNode1 = HasCircle(pHead1);
pNode pMeetNode2 = HasCircle(pHead2);
if (NULL == pMeetNode1&&NULL == pMeetNode2)
{
while (pL1->next)
{
pL1 = pL1->next;
}
while (pL2->next)
{
pL2 = pL2->next;
}
if (pL1 == pL2)
return 1;
}
else if (pMeetNode1&&pMeetNode2)
{
pNode pCurNode = pMeetNode1;
while (pCurNode->next != pMeetNode1)
{
if (pCurNode = pMeetNode2)
return 2;
pCurNode = pCurNode->next;
}
if (pCurNode = pMeetNode2)
return 2;
}
return 0;
}
//
pNode CopyComplexList(pNode pHead)
{
pNode p1 = pHead;
pNode p2 = NULL;
pNode pNewNode = NULL;
if (NULL == pHead)
return NULL;
while (p1)//1、插入结点
{
pNewNode = BuyNode(p1->data);
assert(pNewNode);
pNewNode->next = p1->next;
p1->next = pNewNode;
p1 = p1->next->next;
}
p1 = pHead;
p2 = p1->next;
while (p2->next)//2、随机域赋值
{
if (NULL == p1->random)
p2->random = NULL;
else
p2->random = p1->random->next;
p1 = p2->next;
p2 = p1->next;
}
if (p1->random)
p2->random = p1->random->next;
else
p2->random = NULL;
p1 = pHead;
p2 = p1->next;
pNewNode = p2;
while (p2->next)//3、拆分链表
{
p1->next = p2->next;
p2->next = p1->next->next;
p1 = p1->next;
p2 = p2->next;
}
p2->next = NULL;
return pNewNode;
}
//
//