一、从尾到头打印单链表
//从尾到头打印
void PrintR(SListNode *pFirst)
{
SListNode *pNode = pFirst;
SListNode *pend = NULL;
while (pend != pFirst){
while (pNode->pNext != pend)
{
pNode = pNode->pNext;
}
pend = pNode;
printf("%d ", pNode->data);
pNode = pFirst;
}
}
//递归从尾到头打印
void PrintRshow(SListNode *pFirst)
{
if (pFirst->pNext)
{
PrintRshow(pFirst->pNext);
}
printf("%d-> ", pFirst->data);
}
二、逆置、翻转单链表
//逆置单链表
SListNode *ReverSList(SListNode *pFirst)
{
if (pFirst == NULL)
{
return NULL;
}
SListNode *p1 = NULL;
SListNode *p2 = pFirst;
SListNode *p3 = pFirst->pNext;
while (p2)
{
p2->pNext=p1;
p1 = p2;
p2 = p3;
if (p3 != NULL){
p3 = p3->pNext;
}
}
return p1;
//SListNode *pNewFirst = NULL;
//DataType data;
//while (pFirst != NULL)
//{
// data=pFirst->data;
// PopFront(&pFirst);
// PushFront(&pFirst, data);
//}
//return pNewFirst;
}
三、删除一个无头单链表的非尾结点、无头链表的一个节点前插入一个节点
//删除一个无头单链表的非尾结点(不能遍历链表)
void EraseNoFirstNotTail(SListNode *pPos)
{
assert(pPos != NULL);
SListNode *pNext=pPos->pNext;
pPos->pNext=pNext->pNext;
pPos->data = pNext->data;
free(pNext);
}
//无头链表的一个节点前插入一个节点
void InsertNoFirst(SListNode *pPos, DataType data)
{
SListNode *pNewNode = (SListNode *)malloc(sizeof(SListNode));
assert(pNewNode != NULL);
pNewNode->pNext = pPos->pNext;
pNewNode->data = pPos->data;
pPos->data = data;
pPos->pNext = pNewNode;
}
void TestReplaceMethod()
{
SListNode *pFirst = NULL;
PushBack(&pFirst, 1);
PushBack(&pFirst, 2);
PushBack(&pFirst, 3);
PushBack(&pFirst, 6);
print(pFirst);
SListNode *pFound = Find(pFirst, 3);
//EraseNoFirstNotTail(pFound); //删除一个无头单链表的非尾结点
InsertNoFirst(pFound, 12);//无头链表的一个节点前插入一个节点
print(pFirst);
}
四、合并两个有序链表,合并后依然有序
//合并两个有序链表,合并后依然有序
SListNode *MergeOrderedList(SListNode *p1First, SListNode *p2First)
{
SListNode *p1 = p1First;
SListNode *p2 = p2First;
SListNode *pNewFirst = NULL;
while (p1 != NULL && p2 != NULL)
{
if (p1->data < p2->data)
{
PushBack(&pNewFirst, p1->data);
p1 = p1->pNext;
}
else
{
PushBack(&pNewFirst, p2->data);
p1 = p2->pNext;
}
}
//有一个链表空了
SListNode *pNotEmpty = p1;
if (p1 == NULL)
{
pNotEmpty = p2;
}
//把不空链表余结点插入
while (pNotEmpty)
{
PushBack(&pNewFirst, pNotEmpty->data);
pNotEmpty = pNotEmpty->pNext;
}
return pNewFirst;
}
void TestMergeOrderedList()
{
SListNode *p1First = NULL;
SListNode *p2First = NULL;
PushBack(&p1First, 1);
PushBack(&p2First, 2);
PushBack(&p1First, 3);
PushBack(&p2First, 6);
print(p1First);
print(p2First);
SListNode *pMerged = MergeOrderedList(p1First, p2First);
print(pMerged);
}
五、查找单链表的中间结点,要求只能遍历一次
//查找中间结点,只可以遍历一次
SListNode *FindMiddle(SListNode *pFrist)
{
assert(pFrist != NULL);
SListNode *pFast = pFrist;
SListNode *pSlow = pFrist;
while (1)
{
//快慢指针的结尾需要两次判断
pFast = pFast->pNext;
if (pFast == NULL)
{
break;
}
pFast = pFast->pNext;
if (pFast == NULL)
{
break;
}
pSlow = pSlow->pNext;
}
return pSlow;
}
void TestFindMiddle()
{
SListNode *pFirst = NULL;
PushBack(&pFirst, 1);
PushBack(&pFirst, 2);
PushBack(&pFirst, 3);
PushBack(&pFirst, 4);
PushBack(&pFirst, 5);
PushBack(&pFirst, 6);
PushBack(&pFirst, 7);
print(pFirst);
SListNode *pFound = FindMiddle(pFirst);
printf("%d\n", pFound->data);
}
六、查找单链表的倒数第k个节点,要求只能遍历一次链表
七、求交集
八、约瑟夫环
//约瑟夫环
SListNode *JocephCircle(SListNode *pFirst, int k)
{
//构造循环链表
SListNode *pNode = pFirst;
SListNode *pPrev = NULL;
int i;
while (pNode->pNext)
{
pNode = pNode->pNext;
}
pNode->pNext = pFirst;
//开始执行
pNode = pFirst;
while (pNode->pNext != pNode)
{
//先找到第k个节点,也就是走k-1步
for (i = 0; i < k - 1; i++)
{
pPrev = pNode;
pNode = pNode->pNext;
}
//删除节点
pPrev->pNext = pNode->pNext;
free(pNode);
//让pnode再往下走1步,
pNode = pPrev->pNext;
}
return pNode;
}
void TestJoceph()
{
SListNode *pFirst = NULL;
PushBack(&pFirst, 1);
PushBack(&pFirst, 2);
PushBack(&pFirst, 3);
PushBack(&pFirst, 4);
PushBack(&pFirst, 5);
PushBack(&pFirst, 6);
print(pFirst);
SListNode *pSur = JocephCircle(pFirst,3);
printf("%d\n", pSur->data);
}