链表的基本操作
逆序打印单链表
删除链表的非尾结点,要求:不能遍历链表
在链表pos位置前插入值到data的结点
查找链表的中间结点,要求只能遍历一次链表
查找链表的倒数第K个结点,要求只能遍历一次链表
删除链表的倒数第K个结点,要求只能遍历一次链表
用单链表实现约瑟夫环
链表的逆置–三个指针
链表的逆置–头插法
用冒泡排序思想对单链表进行排序
合并两个有序单链表,合并后依然有序
判断两个单链表是否相交—链表不带环
求两个单链表相交的交点—链表不带环
测试
判断链表是否带环,返回相遇点
获取环的入口点
获取环的长度
判断两个链表是否相交,链表可能带环
测试
逆序打印单链表
void PrintSListFromTail2Head(PNode pHead)
{
PNode pTail = NULL;
PNode pCur = pHead;
PNode pPre = NULL;
if (NULL == pHead)
return;
while (pCur)
{
pTail = pCur;
pCur = pCur->_pNext;
}
while (pTail!=pHead)
{
pCur = pHead;
while (pCur!=pTail)
{
pPre = pCur;
pCur = pCur->_pNext;
}
printf("%d->", pTail->_data);
pTail = pPre;
}
printf("%d->NULL\n", pTail->_data);
//递归实现
#if 0
if(pHead->_pNext)
{
PrintSListFromTail2Head(pHead->_pNext);
}
printf("->%d", pHead->_data);
#endif
}
删除链表的非尾结点,要求:不能遍历链表
void DeleteListNotTailNode(PNode pos)
{
PNode pNext = NULL;
pNext = pos->_pNext;
pos->_data = pNext->_data;
pos->_pNext = pNext->_pNext;
free(pNext);
pNext = NULL;
}
在链表pos位置前插入值到data的结点
/*在链表后边插入,然后将pos的值给后边的,再将值给pos*/
void InesrtPosFront(PNode pos, DataType data)
{
PNode pNext = BuySListNode(data);
pNext->_pNext = pos->_pNext;
pos->_pNext = pNext;
pNext->_data = pos->_data;
pos->_data = data;
}
查找链表的中间结点,要求只能遍历一次链表
/*定义两个指针,一个一次走两步,一个走一步*/
PNode FindMiddleNode(PNode pHead)
{
PNode pFast = pHead;
PNode pSlow = pHead;
if (NULL == pHead)
{
return NULL;
}
else if (NULL == pHead->_pNext)
{
return pHead;
}
else
{
while (pFast&&pFast->_pNext)
{
pFast = pFast->_pNext->_pNext;
pSlow = pSlow->_pNext;
}
return pSlow;
}
}
查找链表的倒数第K个结点,要求只能遍历一次链表
PNode FindLastKNode(PNode pHead, int K)
{
PNode pSlow = pHead;
PNode pFast = pHead;
if (NULL == pHead || K <= 0)
{
return NULL;
}
while (K--)
{
pFast = pFast->_pNext;
}
while (pFast)
{
pFast = pFast->_pNext;
pSlow = pSlow->_pNext;
}
return pSlow;
}
// 删除链表的倒数第K个结点,要求只能遍历一次链表
void DeleteLastKNode(PNode pHead, int K)
{
PNode pSlow = pHead;
PNode pFast = pHead;
PNode pPre = NULL;
if (NULL == pHead || K <= 0)
{
return;
}
while (K--)
{
pFast = pFast->_pNext;
}
while (pFast)
{
pFast = pFast->_pNext;
pPre = pSlow;
pSlow = pSlow->_pNext;
}
pPre->_pNext = pSlow->_pNext;
free(pSlow);
pSlow = NULL;
}
用单链表实现约瑟夫环
void JosephCircle(PNode* pHead, const int M)
{
PNode pCur = NULL;
PNode pDel = NULL;
int count = 0 ;
assert(pHead);
if (NULL == *pHead|| M <= 0)
{
return;
}
pCur = *pHead;
//先遍历链表,让尾指向头
while (pCur->_pNext)
{
pCur = pCur->_pNext;
}
pCur->_pNext = *pHead;
pCur = *pHead;
while ((pCur)->_pNext != pCur)
{
count = M;
while (--count) //为什么时--M
{
pCur = pCur->_pNext;
}
//删节点
pDel = pCur->_pNext;
pCur->_data = pDel->_data;
pCur->_pNext = pDel->_pNext;
free(pDel);
pDel = NULL;
}
//解环
pCur->_pNext = NULL;
SListPrint(pCur);
}
链表的逆置–三个指针
void ReverseSList(PNode* pHead)
{
PNode pPre = NULL;
PNode pCur = NULL;
PNode pNext = NULL;
assert(pHead);
pCur = *pHead;
while (pCur)
{
pNext = pCur->_pNext;
pCur->_pNext = pPre;
pPre = pCur;
pCur = pNext;
}
*pHead = pPre;
}
链表的逆置–头插法
PNode ReverseSListOP(PNode pHead)
{
PNode pCur = NULL;
PNode pNewNode= NULL;
if (NULL == pHead || NULL == pHead->_pNext)
return NULL;
while (pHead)
{
pCur = pHead;
pHead = pCur->_pNext;
pCur->_pNext = pNewNode;
pNewNode = pCur;
}
pHead = pCur;
return pHead;
}
用冒泡排序思想对单链表进行排序
void BubbleSort(PNode pHead)
{
PNode pTail = NULL;
PNode pCur = pHead;
int flag = 0;
if (pHead == NULL || pHead->_pNext == NULL)
{
return;
}
while (pTail != pHead)
{
pCur = pHead;
flag = 0;
//这里为pCur->_pNext是为了防止if语句的中pCur->_pNext为空,如果为空第一次比较程序就会崩溃
while (pCur->_pNext != pTail)
{
if (pCur->_data < pCur->_pNext->_data)
{
DataType temp = pCur->_data;
pCur->_data = pCur->_pNext->_data;
pCur->_pNext->_data = temp;
flag = 1;
}
pCur = pCur->_pNext;
}
pTail = pCur;
if (0 == flag)
break;
}
}
合并两个有序单链表,合并后依然有序
PNode MergeSList(PNode pHead1, PNode pHead2)
{
PNode pNewHead = NULL;
PNode pCur = NULL;
if (!pHead1)
return pHead2;
if (!pHead2)
return pHead1;
if (pHead1->_data >= pHead2->_data)
{
pCur = BuySListNode(pHead2->_data);
pHead2 = pHead2->_pNext;
pNewHead = pCur;
}
else if (pHead1->_data < pHead2->_data)
{
pCur = BuySListNode(pHead1->_data);
pHead1 = pHead1->_pNext;
pNewHead = pCur;
}
while (pHead1&&pHead2)
{
if (pHead1->_data >= pHead2->_data)
{
pCur->_pNext = BuySListNode(pHead2->_data);
pHead2 = pHead2->_pNext;
pCur = pCur->_pNext;
}
else if (pHead1->_data < pHead2->_data)
{
pCur->_pNext = BuySListNode(pHead1->_data);
pHead1 = pHead1->_pNext;
pCur = pCur->_pNext;
}
}
while (pHead1)
{
pCur->_pNext = BuySListNode(pHead1->_data);
pHead1 = pHead1->_pNext;
pCur = pCur->_pNext;
}
while (pHead2)
{
pCur->_pNext = BuySListNode(pHead2->_data);
pHead2= pHead2->_pNext;
pCur = pCur->_pNext;
}
return pNewHead;
}
判断两个单链表是否相交—链表不带环
int IsSListCross(PNode pHead1, PNode pHead2)
{
if (NULL == pHead1 || NULL == pHead2)
return 0;
//找到链表的最后一个节点
while (pHead1->_pNext)
{
pHead1 = pHead1->_pNext;
}
while (pHead2->_pNext)
{
pHead2 = pHead2->_pNext;
}
if (pHead1 == pHead2)
{
return 1;
}
else
{
return 0;
}
}
求两个单链表相交的交点—链表不带环
/*先让长的链表遍历size1-size2,再让两个链表一起遍历,
当pCur1==pCur2时,两链表相交*/
PNode GetCorssNode(PNode pHead1, PNode pHead2)
{
if (NULL == pHead1 || NULL == pHead2)
return NULL;
int size1 = 0;
int size2 = 0;
int gap = 0;
PNode pCur1 = pHead1;
PNode pCur2 = pHead2;
while (pCur1)
{
pCur1 = pCur1->_pNext;
size1++;
}
while (pCur2)
{
pCur2 = pCur2->_pNext;
size2++;
}
gap = size1 - size2;
pCur1 = pHead1; pCur2 = pHead2;
if (gap > 0)
{
while (gap--)
{
pCur1 = pCur1->_pNext;
}
}
else
{
while (gap++)
{
pCur2 = pCur2->_pNext;
}
}
while (pCur1 != pCur2)
{
pCur1 = pCur1->_pNext;
pCur2 = pCur2->_pNext;
}
return pCur2;
}
测试程序
void TestInterview()
{
PNode pHead1, pHead2,pCur;
SListInit(&pHead1);
SListPushBlack(&pHead1, 1);
SListPushBlack(&pHead1, 5);
SListPushBlack(&pHead1, 9);
SListPushBlack(&pHead1, 3);
SListPushBlack(&pHead1, 6);
SListPushBlack(&pHead1, 34);
SListPrint(pHead1);
SListInit(&pHead2);
SListPushBlack(&pHead2, 2);
SListPushBlack(&pHead2, 4);
pHead2->_pNext->_pNext = SListFind(pHead1,6);
SListPrint(pHead2);
pCur = GetCorssNode(pHead1, pHead2);
//int ret = IsSListCross(pHead1, pHead2);
//SListPushBlack(&pHead2, 6);
//SListPushBlack(&pHead2, 34);
//SListPrint(pHead2);
//pCur = MergeSList(pHead1, pHead2);
//SListPrint(pCur);
//PrintSListFromTail2Head(pHead);
//pCur = SListFind(pHead, 6);
//DeleteListNotTailNode(pCur);
//InesrtPosFront(pCur, 5);
//SListPrint(pHead);
/*pCur = FindMiddleNode(pHead);*/
//pCur = FindLastKNode(pHead, 3);
//DeleteLastKNode(pHead, 3);
//SListPrint(pHead);
//JosephCircle(&pHead, 3);
//ReverseSList(&pHead);
/*SListPrint(pHead);
pHead = ReverseSListOP(pHead);
SListPrint(pHead);*/
/*BubbleSort(pHead);
SListPrint(pHead);*/
}
判断两个链表是否相交,链表可能带环
PNode IsListWithCircle(PNode pHead1)
{
PNode pFast = pHead1;
PNode pSlow = pHead1;
if (NULL == pHead1)
return NULL;
while (pFast && pFast->_pNext)
{
pFast = pFast->_pNext->_pNext;
pSlow = pSlow->_pNext;
if (pSlow == pFast)
return pSlow;
}
return NULL;
}
获取环的入口点
PNode GetCircleEnter(PNode pHead1, PNode pMeetNode)
{
PNode pH = pHead1;
PNode pM = pMeetNode;
if (NULL == pHead1 || NULL == pMeetNode)
{
return NULL;
}
else
{
while (pH != pM)
{
pH = pH->_pNext;
pM = pM->_pNext;
}
}
return pM;
}
获取环的长度
int GetCircleLen(PNode pMeetNode)
{
PNode pCur = pMeetNode;
int len = 1;
if (NULL == pMeetNode)
{
return 0;
}
else
{
while (pCur->_pNext != pMeetNode)
{
pCur = pCur->_pNext;
len++;
}
}
return len;
}
判断两个链表是否相交,链表可能带环
int IsSListCrossWithCircle(PNode pHead1, PNode pHead2)
{
PNode pSlow = NULL;
PNode pFast = NULL;
if (NULL == pHead1 || NULL == pHead2)
return 0;
pSlow = pHead1;
pFast = pHead2;
while (pFast&&pFast->_pNext)
{
pFast = pFast->_pNext->_pNext;
pSlow = pSlow->_pNext;
if (pFast == pSlow)
return 1;
}
return 0;
}
测试
void TestInterview2()
{
PNode pHead, pCur;
SListInit(&pHead);
SListPushBlack(&pHead, 1);
SListPushBlack(&pHead, 3);
SListPushBlack(&pHead, 6);
SListPushBlack(&pHead, 9);
SListPushBlack(&pHead, 7);
SListPushBlack(&pHead, 4);
SListPushBlack(&pHead, 8);
SListPrint(pHead);
pCur = pHead;
while (NULL != pCur->_pNext)
pCur = pCur->_pNext;
pCur->_pNext = SListFind(pHead, 7);
PNode pMeetNode = IsListWithCircle(pHead);
PNode pEnterNode = GetCircleEnter(pHead, pMeetNode);
int len = GetCircleLen(pMeetNode);
}
复杂链表的复制
PCSLNode CopyComplexList(PCSLNode pHead)
{
PCSLNode pCur = pHead;
PCSLNode pNewNode = NULL;
PCSLNode pNewHead = NULL;
if (NULL == pHead)
return NULL;
//1.在链表后面插入值相同的新节点
while (pCur)
{
pNewNode = BuyCSNewNode(pCur->data);
pNewNode->_pNext = pCur->_pNext;
pCur->_pNext = pNewNode;
pCur = pNewNode->_pNext;
}
pCur = pHead;
//2.给新节点的随机指针域赋值
//让随机指针域指向原节点随机指针指向的下个节点
while (pCur)
{
pNewNode = pCur->_pNext;
if (pCur->_pRandom)
{
pNewNode->_pRandom = pCur->_pRandom->_pNext;
}
pCur = pNewNode->_pNext;
}
//3.将新节点从原链表中拆下来
pCur = pHead;
pNewHead = pHead->_pNext;
while (pCur->_pNext)
{
pNewNode = pCur->_pNext;
pCur->_pNext = pNewNode->_pNext;
pCur = pNewNode;
}
return pNewHead;
}