1.链表逆序
//倒置链表
int ReversalLinkList(LinkNode *pHead)
{
LinkNode *pTmpNode = NULL;
LinkNode *pInsertNode = NULL;
pTmpNode = pHead->pNext;
pHead->pNext = NULL;
pInsertNode = pTmpNode;
while (pTmpNode != NULL)
{
pTmpNode = pTmpNode->pNext;
pInsertNode->pNext = pHead->pNext;
pHead->pNext = pInsertNode;
pInsertNode = pTmpNode;
}
return 0;
}
2.删除倒数第n个节点
//找到链表倒数第k个节点
//算法:
// 快指针先走k步
// 慢指针和快指针每次走1步(快指针总是领先慢指针k步)
// 当快指针走到末尾时,慢指针即指向链表倒数第k个节点
LinkNode *FindLastKthLinkNode(LinkNode *pHead, int k)
{
LinkNode *pFast = pHead->pNext;
LinkNode *pSlow = pHead->pNext;
int i = 0;
for (i = 0; i < k; i++)
{
pFast = pFast->pNext;
if (NULL == pFast)
{
break;
}
}
if (NULL == pFast)
{
return NULL;
}
while (pFast != NULL)
{
pSlow = pSlow->pNext;
pFast = pFast->pNext;
}
return pSlow;
}
3.判断有环
//判断链表是否有环
//实现方式:
// 快指针每次走2步,慢指针每次走1步
// 两者能够相遇即为有环
LinkNode *IsHasCircle(LinkNode *pHead, int *pcnt)
{
LinkNode *pFast = NULL;
LinkNode *pSlow = NULL;
LinkNode *pTmpNode = NULL;
LinkNode *pNode1 = NULL;
LinkNode *pNode2 = NULL;
int ret = 0;
int cnt = 1;
pSlow = pFast = pHead->pNext;
while (1)
{
pFast = pFast->pNext;
if (NULL == pFast)
{
ret = 0;
break;
}
pFast = pFast->pNext;
if (NULL == pFast)
{
ret = 0;
break;
}
pSlow = pSlow->pNext;
if (pSlow == pFast)
{
ret = 1;
break;
}
}
if (1 == ret)
{
//获得环长
pTmpNode = pSlow->pNext;
while (pTmpNode != pSlow)
{
cnt++;
pTmpNode = pTmpNode->pNext;
}
*pcnt = cnt;
//获得环入口位置
pNode1 = pSlow;
pNode2 = pHead->pNext;
while (1)
{
pNode1 = pNode1->pNext;
pNode2 = pNode2->pNext;
if (pNode1 == pNode2)
{
return pNode1;
}
}
}
return NULL;
}
4.创建双向循环链表
#include "doulist.h"
//创建双向链表
LinkNode *CreateDouList(void)
{
LinkNode *pTmpNode = NULL;
pTmpNode = malloc(sizeof(LinkNode));
if (NULL == pTmpNode)
{
return NULL;
}
pTmpNode->pPre = NULL;
pTmpNode->pNext = NULL;
return pTmpNode;
}
//头插法插入
int HeadInsertDouList(LinkNode *pHead, DataType TmpData)
{
LinkNode *pNewNode = NULL;
pNewNode = malloc(sizeof(LinkNode));
if (NULL == pNewNode)
{
return -1;
}
pNewNode->Data = TmpData;
pNewNode->pNext = pHead->pNext;
pNewNode->pPre = pHead;
pHead->pNext = pNewNode;
if (pNewNode->pNext != NULL)
{
pNewNode->pNext->pPre = pNewNode;
}
return 0;
}
//删除链表节点
int DeleteDouList(LinkNode *pHead, DataType TmpData)
{
LinkNode *pTmpNode = NULL;
LinkNode *pNextNode = NULL;
int cnt = 0;
pTmpNode = pHead->pNext;
while (pTmpNode != NULL)
{
if (pTmpNode->Data == TmpData)
{
pNextNode = pTmpNode->pNext;
pTmpNode->pPre->pNext = pTmpNode->pNext;
if (pTmpNode->pNext != NULL)
{
pTmpNode->pNext->pPre = pTmpNode->pPre;
}
free(pTmpNode);
pTmpNode = pNextNode;
cnt++;
}
else
{
pTmpNode = pTmpNode->pNext;
}
}
return cnt;
}
//正向遍历
int FrontShowDouList(LinkNode *pHead)
{
LinkNode *pTmpNode = NULL;
pTmpNode = pHead->pNext;
while (pTmpNode != NULL)
{
printf("%d ", pTmpNode->Data);
pTmpNode = pTmpNode->pNext;
}
printf("\n");
return 0;
}
//反向遍历
int BehindShowDouList(LinkNode *pHead)
{
LinkNode *pTmpNode = NULL;
pTmpNode = pHead;
while (pTmpNode->pNext != NULL)
{
pTmpNode = pTmpNode->pNext;
}
while (pTmpNode != pHead)
{
printf("%d ", pTmpNode->Data);
pTmpNode = pTmpNode->pPre;
}
printf("\n");
return 0;
}
//尾插法
int TailInsertDouList(LinkNode *pHead, DataType TmpData)
{
LinkNode *pLastNode = NULL;
LinkNode *pTmpNode = NULL;
pLastNode = pHead;
while (pLastNode->pNext != NULL)
{
pLastNode = pLastNode->pNext;
}
pTmpNode = malloc(sizeof(LinkNode));
if (NULL == pTmpNode)
{
return -1;
}
pTmpNode->Data = TmpData;
pTmpNode->pNext = NULL;
pTmpNode->pPre = pLastNode;
pLastNode->pNext = pTmpNode;
return 0;
}
//销毁
int DestroyDouList(LinkNode **ppHead)
{
LinkNode *pFreeNode = NULL;
LinkNode *pTmpNode = NULL;
pTmpNode = *ppHead;
pFreeNode = *ppHead;
while (pTmpNode != NULL)
{
pTmpNode = pTmpNode->pNext;
free(pFreeNode);
pFreeNode = pTmpNode;
}
*ppHead = NULL;
return 0;
}