1.求单链表中结点的个数
// 求单链表中结点的个数
unsigned int GetListLength(ListNode * pHead)
{
if(pHead == NULL) return 0;
unsigned int nLength = 0;
ListNode * pCurrent = pHead;
while(pCurrent != NULL)
{
nLength++;
pCurrent = pCurrent->m_pNext;
}
return nLength;
}
2.将单链表反转
// 反转单链表
ListNode * ReverseList(ListNode * pHead)
{
// 如果链表为空或只有一个结点,无需反转,直接返回原链表头指针
if(pHead == NULL || pHead->m_pNext == NULL)
return pHead;
ListNode * pReversedHead = NULL;
// 反转后的新链表头指针,初始为NULL
ListNode * pCurrent = pHead;
while(pCurrent != NULL)
{
ListNode * pTemp = pCurrent;
pCurrent = pCurrent->m_pNext;
pTemp->m_pNext = pReversedHead;
// 将当前结点摘下,插入新链表的最前端
pReversedHead = pTemp;
}
return pReversedHead;
}
3. 查找单链表中的倒数第K个结点(k > 0)
// 查找单链表中倒数第K个结点
ListNode * RGetKthNode(ListNode * pHead, unsigned int k)
// 函数名前面的R代表反向
{
if(k == 0 || pHead == NULL)
// 这里k的计数是从1开始的,若k为0或链表为空返回NULL
return NULL;
ListNode * pAhead = pHead;
ListNode * pBehind = pHead;
// 前面的指针先走到正向第k个结点
while(k > 1 && pAhead != NULL)
{
pAhead = pAhead->m_pNext;
k--;
}
if(k > 1)
// 结点个数小于k,返回NULL
return NULL;
// 前后两个指针一起向前走,直到前面的指针指向最后一个结点
while(pAhead->m_pNext != NULL)
{
pBehind = pBehind->m_pNext;
pAhead = pAhead->m_pNext;
}
return pBehind;
// 后面的指针所指结点就是倒数第k个结点
}
4.查找单链表的中间结点
// 获取单链表中间结点,若链表长度为n(n>0),则返回第n/2+1个结点
ListNode * GetMiddleNode(ListNode * pHead)
{
if(pHead == NULL || pHead->m_pNext == NULL)
// 链表为空或只有一个结点,返回头指针
return pHead;
ListNode * pAhead = pHead;
ListNode * pBehind = pHead;
while(pAhead->m_pNext != NULL)
// 前面指针每次走两步,直到指向最后一个结点,后面指针每次走一步
{
pAhead = pAhead->m_pNext;
pBehind = pBehind->m_pNext;
if(pAhead->m_pNext != NULL)
pAhead = pAhead->m_pNext;
}
return pBehind; // 后面的指针所指结点即为中间结点
}
5. 从尾到头打印单链表
// 从尾到头打印链表,使用栈
void RPrintList(ListNode * pHead)
{
std::stack<ListNode *> s;
ListNode * pNode = pHead;
while(pNode != NULL)
{
s.push(pNode);
pNode = pNode->m_pNext;
}
while(!s.empty())
{
pNode = s.top();
printf("%d\t", pNode->m_nKey);
s.pop();
}
}
使用递归函数
// 从尾到头打印链表,使用递归
void RPrintList(ListNode * pHead)
{
if(pHead == NULL)
{
return;
}
else
{
RPrintList(pHead->m_pNext);
printf("%d\t", pHead->m_nKey);
}
}
6. 已知两个单链表pHead1 和pHead2 各自有序,把它们合并成一个链表依然有序
// 合并两个有序链表
ListNode * MergeSortedList(ListNode * pHead1, ListNode * pHead2)
{
if(pHead1 == NULL)
return pHead2;
if(pHead2 == NULL)
return pHead1;
ListNode * pHeadMerged = NULL;
if(pHead1->m_nKey < pHead2->m_nKey)
{
pHeadMerged = pHead1;
pHeadMerged->m_pNext = NULL;
pHead1 = pHead1->m_pNext;
}
else
{
pHeadMerged = pHead2;
pHeadMerged->m_pNext = NULL;
pHead2 = pHead2->m_pNext;
}
ListNode * pTemp = pHeadMerged;
while(pHead1 != NULL && pHead2 != NULL)
{
if(pHead1->m_nKey < pHead2->m_nKey)
{
pTemp->m_pNext = pHead1;
pHead1 = pHead1->m_pNext;
pTemp = pTemp->m_pNext;
pTemp->m_pNext = NULL;
}
else
{
pTemp->m_pNext = pHead2;
pHead2 = pHead2->m_pNext;
pTemp = pTemp->m_pNext;
pTemp->m_pNext = NULL;
}
}
if(pHead1 != NULL)
pTemp->m_pNext = pHead1;
else if(pHead2 != NULL)
pTemp->m_pNext = pHead2;
return pHeadMerged;
}
也有如下递归解法:
ListNode * MergeSortedList(ListNode * pHead1, ListNode * pHead2)
{
if(pHead1 == NULL)
return pHead2;
if(pHead2 == NULL)
return pHead1;
ListNode * pHeadMerged = NULL;
if(pHead1->m_nKey < pHead2->m_nKey)
{
pHeadMerged = pHead1;
pHeadMerged->m_pNext=MergeSortedList(pHead1->m_pNext,pHead2);
}
else
{
pHeadMerged = pHead2;
pHeadMerged->m_pNext=MergeSortedList(pHead1,pHead2->m_pNext);
}
return pHeadMerged;
}
7. 判断一个单链表中是否有环
bool HasCircle(ListNode * pHead)
{
// 快指针每次前进两步
ListNode * pFast = pHead;
// 慢指针每次前进一步
ListNode * pSlow = pHead;
while(pFast != NULL && pFast->m_pNext != NULL)
{
pFast = pFast->m_pNext->m_pNext;
pSlow = pSlow->m_pNext;
if(pSlow == pFast) // 相遇,存在环
return true;
}
return false;
}