SList.h
void PrintListFromTail2Head(PNode pHead);//从尾到头打印单链表
void EraseNotTailNode(PNode pos);//删除非尾结点
void InsertFront(PNode pos,DataType data);//无头单链表插入结点
void JosephCircle(PNode *ppHead,size_t M);//约瑟夫环
void ReverseList(PNode *ppHead);//链表逆置
PNode ReverseList_P(PNode pHead);//链表逆置(头插法)
void BubbleSort(PNode pHead);//冒泡排序
PNode FindMidlleNode(PNode pHead);//查找单链表的中间结点,要求只能遍历一次
PNode FindLastKNode(PNode pHead, size_t K);// 查找单链表的倒数第K个结点
int DeleteLastKNode(PNode* ppHead,size_t K);//删除倒数第k个结点
PNode MergeLiist(PNode pHead1,PNode pHead2);//合并两个有序的单链表
PNode HasCircle(PNode pHead);//判断单链表是否带环
size_t GetCircleLen(PNode pHead);//求环的长度
SList.c
void PrintListFromTail2Head(PNode pHead)//打印结点
//采用函数递归 1-->2-->3--4-->NULL 递归了5次
//时间复杂度:O(N+1) //空间复杂度:O(N+1)
{
if (pHead)
{
PrintListFromTail2Head(pHead->_pNext);
printf("%d ",pHead->_data);
}
//循环实现
//...
}
void EraseNotTailNode(PNode pos)//替换法删除(腾讯面试题)
{
PNode pDel;
if (NULL == pos || NULL == pos->_pNext)
return;
pDel = pos->_pNext;//pDel初始化为pos结点的下一个结点位置
pos->_data = pDel->_data;//将要删除的结点数据赋给pos结点。
pos->_pNext = pDel->_pNext;//使得pos的下一个结点指向删除结点的下一个结点
free(pDel);//删除结点
}
void InsertFront(PNode pos, DataType data)//无头单链表插入结点
{
PNode pNewNode = NULL;
if (NULL == pos)
free(pNewNode);
return;
pNewNode = BuySListNode(pos->_data);
pNewNode->_pNext = pos->_pNext;
pos->_pNext = pNewNode;
pos->_data = data;
}
void JosephCircle(PNode *ppHead, size_t M)//约瑟夫环
{
PNode pCur = NULL;
assert(ppHead);
pCur = *ppHead;
while (pCur != pCur->_pNext)
{
//1.报数:
size_t count = M;
PNode pDel = NULL;
while (--count)
pCur = pCur->_pNext;
//2.删除:(替换法)---(非尾结点)
pDel = pCur->_pNext;
pCur->_data = pDel->_data;
pCur->_pNext = pDel->_pNext;
free(pDel);
}
*ppHead = pCur;
}
void ReverseList(PNode *ppHead)//链表逆置 (以下两种方法均不能处理带环问题,如果要处理,可先将环拆开,然后按照正常方法进行逆置,最后将头尾结点指向头结点即可)
{
PNode pPre = NULL;
PNode pCur = NULL;
PNode pNext = NULL;
if (NULL == ppHead || NULL == (*ppHead)->_pNext)
return;
pCur = *ppHead;
while (pCur)
{
pNext = pCur->_pNext;
pCur->_pNext = pPre;
pPre = pCur;
pCur = pNext;
}
*ppHead = pPre; //已经变成头结点,更新头结点
}
PNode ReverseList_P(PNode pHead)//链表逆置(带环:将pHead指向pNewHead)
{
PNode pCur = pHead;
PNode pNext = NULL;
PNode pNewHead = NULL;
while (pCur)
{
pNext = pCur->_pNext;
pCur->_pNext = pNewHead;//先链接
pNewHead = pCur;
pCur = pNext;
}
return pNewHead;
}
void BubbleSort(PNode pHead)//冒泡排序
{
PNode pCur = NULL;
PNode pNext = NULL;
PNode pTail = NULL;
int IsChange = 0;//设置一个标记
if (NULL == pHead || NULL == pHead->_pNext)
return;
while (pHead != pTail)
{
pCur = pHead;
pNext = pCur->_pNext;
IsChange = 0;//恢复标记
while (pNext != pTail)
{
if (pCur->_data > pNext->_data)
{
DataType temp = pCur->_data;
pCur->_data = pNext->_data;
pNext->_data = temp;
IsChange = 1;//还没有排好
}
pCur = pNext;
pNext = pCur->_pNext;
}
if (!IsChange)
return;
pTail = pCur;
}
}
PNode FindMidlleNode(PNode pHead)//寻找中间结点
{
PNode pSlow = pHead;
PNode pFast = pHead;
while (pFast && pFast->_pNext)//保证第一步和第二步都走成功
{
pSlow = pSlow->_pNext;
pFast = pFast->_pNext->_pNext;
}
return pSlow;
}
PNode FindLastKNode(PNode pHead,size_t K)//寻找倒数第K个结点 //时间复杂度:O(N)
{
PNode pFast = pHead;
PNode pSlow = pHead;
if (NULL == pHead || 0 == K)
return NULL;
//. 定义两个指针pFast和pSlow 让pFast先走k步(k--)---> pFast == NULL
//k-1步(--k) ----> pFast->next == NULL
while (--K)
{
if (NULL == pFast)
return NULL;
pFast = pFast->_pNext;
}
//然后同时走
while (pFast->_pNext)
{
pSlow = pSlow->_pNext;
pFast = pFast->_pNext;
}
return pSlow;
}
int DeleteLastKNode(PNode* ppHead, size_t K)//删除倒数第K个结点
{
PNode pFast = NULL;
PNode pSlow = NULL;
PNode pPreSlow = NULL;
assert(ppHead);
if (NULL == *ppHead || 0 == K)
return 0;
pFast = pSlow = *ppHead;
while (K--)
{
if (NULL == pFast)
return 0;
pFast = pFast->_pNext;
}
while (pFast)
{
pPreSlow = pSlow;
pSlow = pSlow->_pNext;
pFast = pFast->_pNext;
}
if (pSlow == *ppHead)
*ppHead = pSlow->_pNext;
else
pPreSlow->_pNext = pSlow->_pNext;
free(pSlow);
return 1;
}
PNode MergeLiist(PNode pHead1, PNode pHead2)//合并两个有序单链表
{
PNode pL1 = pHead1;
PNode pL2 = pHead2;
PNode pNewNode = NULL;
PNode pTail = NULL;
if (NULL == pHead1 || NULL == pHead2)
return (pHead1) ? pHead1 : pHead2;
if (pL1->_data < pL2->_data)
{
pNewNode = pL1;
pTail = pL1;//标记
pL1 = pL1->_pNext;
}
else
{
pNewNode = pL2;
pTail = pL2;
pL2 = pL2->_pNext;
}
while (pL1 && pL2)
{
if (pL1->_data < pL2->_data)
{
pTail->_pNext = pL1;
pL1 = pL1->_pNext;
}
else
{
pTail->_pNext = pL2;
pL2 = pL2->_pNext;
}
pTail = pTail->_pNext;
}
if (pL1)
pTail->_pNext = pL1;
if (pL2)
pTail->_pNext = pL2;
return pNewNode;
}
PNode HasCircle(PNode pHead)//判断单链表是否带环
{
PNode pFast = pHead;
PNode pSlow = pHead;
while (pFast && pFast->_pNext)
{
pFast = pFast->_pNext->_pNext;
pSlow = pSlow->_pNext;
if (pFast == pSlow)
return 1;
}
return 0;
}
size_t GetCircleLen(PNode pHead)//求环的长度(R)
{
PNode pMeetNode = HasCircle(pHead);
PNode pCur;
size_t len = 1;
if (NULL == pMeetNode)
return 0;
pCur = pMeetNode;
while (pCur->_pNext != pMeetNode)
{
len++;
pCur = pCur->_pNext;
}
return len;
}
Test.c
void TestSList5()
{
PNode pHead;//给出结点
SListInit(&pHead);//初始化
SListPushBack(&pHead, 1);
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
SListPrint(pHead);
PrintListFromTail2Head(pHead);
}
void TestSList6()//测试约瑟夫环
{
PNode pHead,pTailNode;//给出结点
SListInit(&pHead);//初始化
SListPushBack(&pHead, 1);
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
SListPushBack(&pHead, 5);
SListPushBack(&pHead, 6);
SListPushBack(&pHead, 7);
SListPrint(pHead);
pTailNode = Find(pHead,7);
pTailNode->_pNext = pHead;
JosephCircle(&pHead,3);
pHead->_pNext = NULL;
}
void TestSList7()//链表逆置
{
PNode pHead;//给出结点
SListInit(&pHead);//初始化
SListPushBack(&pHead, 1);
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
SListPushBack(&pHead, 5);
SListPushBack(&pHead, 6);
SListPushBack(&pHead, 7);
SListPrint(pHead);
//ReverseList(&pHead);
pHead = ReverseList_P(pHead);
SListPrint(pHead);
}
void TestSList8()//冒泡排序
{
PNode pHead;//给出结点
SListInit(&pHead);//初始化
SListPushBack(&pHead, 1);
SListPushBack(&pHead, 7);
SListPushBack(&pHead, 5);
SListPushBack(&pHead, 4);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 6);
SListPushBack(&pHead, 9);
SListPrint(pHead);
BubbleSort(pHead);
SListPrint(pHead);
}
void TestSList9()//寻找倒数第k个结点
{
PNode pHead,pNode;//给出结点
SListInit(&pHead);//初始化
SListPushBack(&pHead, 1);
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
SListPushBack(&pHead, 5);
SListPushBack(&pHead, 6);
SListPrint(pHead);
pNode = FindLastKNode(pHead, 6);
if (pNode)
{
printf("%d\n",pNode->_data);
}
DeleteLastKNode(&pHead, 6);
SListPrint(pHead);
DeleteLastKNode(&pHead, 2);
SListPrint(pHead);
}
//////////讲解到2017.12.17 15:26
void TestSList10()
{
PNode pHead1, pHead2, pNewHead;//给出结点
SListInit(&pHead1);//初始化
SListPushBack(&pHead1, 1);
SListPushBack(&pHead1, 3);
SListPushBack(&pHead1, 5);
SListPushBack(&pHead1, 7);
SListPrint(pHead1);
SListInit(&pHead2);//初始化
SListPushBack(&pHead2, 2);
SListPushBack(&pHead2, 4);
SListPushBack(&pHead2, 4);
SListPushBack(&pHead2, 6);
SListPrint(pHead2);
pNewHead = MergeLiist(pHead1, pHead2);
SListPrint(pNewHead);
}