本博客内容
1、单链表的结构
2、求链表的长度
3、单链表反转
4、单链表倒数第k个节点
5、查找链表的中间节点
6、从尾到头打印链表
7、已知2个单链表有序,把它们合并为一个有序链表
8、判断一个单链表是否有环
9、判断2个链表是否相交
10、求2个单链表相交的第1个节点
1、单链表的结构
struct ListNode
{
int m_nValue;
ListNode * m_pNext;
};
2、求链表的长度
unsigned int GetListLength(ListNode * pHead)</font>
{
if(pHead==NULL)
return 0;
ListNode * pNode=pHead;
unsigned int length=0;
while(pNode)
{
length++;
pNode=pNode->m_pNext;
}
return length;
}
3、单链表反转
① 采用交换的方法
ListNode * ReverseList(ListNode * pHead)
{
if(!pHead||!pHead->m_pNext)
return pHead;
ListNode * pReverseHead=NULL;
ListNode * pNode=pHead;
ListNode * pPrev=NULL;
while(pNode)
{
ListNode * pNext=pNode->m_pNext;
if(!pNext)
pReverseHead=pNode;
pNode->m_pNext=pPrev;
pPrev=pNode;
pNode=pNext;
}
return pReverseHead;
②递归方法
ListNode * ReverseList(ListNode * pHead)
{
if(!pHead||!pHead->m_pNext)
return pHead;
ListNode * result=ReverseList(pHead->m_pNext);
pHead->m_pNext->m_pNext=pHead;
pHead->m_pNext=NULL;
return result;
}
③使用辅助栈空间
ListNode * ReverseList(ListNode * pHead)
{
if(!pHead||!pHead->m_pNext)
return pHead;
stack<ListNode * > stk;
ListNode * pNode=pHead;
while(pNode->m_pNext)
{
stk.push(pNode);
pNode=pNode->m_pNext;
}
//此时pNode指向最后一个节点
ListNode * result=pNode;
while(!stk.empty())
{
pNode->m_pNext=stk.top();
pNode=pNode->m_pNext;
stk.pop();
}
pNode->m_pNext=NULL;
return result;
}
4、单链表倒数第k个节点
ListNode * GetLastKNode(ListNode *pHead,unsigned int k)
{
if(!pHead||k<=0)
return NULL;
ListNode * pNode=pHead;
//快指针先走k-1步
unsigned int length=0;
while(pNode)
{
length++;
pNode=pNode->m_pNext;
}
if(k>length)
return NULL; //此处对k进行最大值判断
ListNode * fastList=pHead;
ListNode * slowList=pHead;
while(--k>0)
{
if(fastList->m_pNext) //需要判断是否存在下一个节点
fastList=fastList->m_pNext;
else
return NULL;
}
while(!fastList->m_pNext)
{
fastList=fastList->m_pNext;
slowList=slowList->m_pNext;
}
return slowList;
}
5、查找链表的中间节点
//原理,和倒数第k个节点一样,采用快慢指针
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) //此处需要判断快指针是否有后续节点
pAhead=pAhead->m_pNext;
}
return pBehind;
}
6、从尾到头打印链表
①辅助栈
void PrintList(ListNode * pHead)
{
if(pHead==NULL)
return ;
stack<ListNode * > stk;
ListNode * pNode=pHead;
while(pNode)
{
stk.push(pNode);
pNode=pNode->m_pNext;
}
while(!stk.empty())
{
printf("%d\t",stk.top()->m_nValue);
stk.pop();
}
}
②递归
void PrintList(ListNode * pHead)
{
if(pHead==NULL)
return ;
else
{
PrintList(pHead->m_pNext);
printf("%d\t",pHead->m_nValue);
}
}
7、已知2个单链表有序,把它们合并为一个有序链表
①递归
//递归操作相对简单
ListNode * MergeList(ListNode * pHead1,ListNode * pHead2)
{
if(!pHead1) return pHead2;
if(!pHead2) return pHead1;
ListNode * result=NULL;
if(pHead1->m_nValue<=pHead2->m_nValue)
{
result=pHead1;
result->m_pNext=MergeList(pHead1->m_pNext,pHead2);
}
else
{
result=pHead2;
result->m_pNext=MergeList(pHead1,pHead2->m_pNext);
}
return result;
}
②循环
ListNode * MergeList(ListNode * pHead1,ListNode * pHead2)
{
if(pHead1==NULL) return pHead2;
if(pHead2==NULL) return pHead1;
ListNode * pHeadMerged=NULL;
if(pHead1->m_nValue<pHead2->m_nValue)//先确定链表头部
{
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_nValue<pHead2->m_nValue)
{
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;
}
8、判断一个单链表是否有环
bool HasCircle(ListNode * pHead)
{
ListNode * pFast=pHead;
ListNode * pSlow=pHead;
while(pFast||pFast->m_pNext) //需要有条件判断
{
pFast=pFast->m_pNext->m_pNext;
pSlow=pSlow->m_pNext;
if(pSlow==pFast)
return true;
}
return false;
}
9、判断2个链表是否相交
//思路:如果2个链表相交,则它们最后一个节点肯定相同
bool IsInterseted(ListNode * pHead1,ListNode * pHead2)
{
if(pHead1==NULL || pHead2==NULL)
return false;
ListNode * pTail1=pHead1;
while(pTail1->m_pNext!=NULL)
pTail1=pTail1->m_pNext;
ListNode * pTail2=pHead2;
while(pTail2->m_pNext!=NULL)
pTail2=pTail2->m_pNext;
return pTail1==pTail2;
}
10、求2个单链表相交的第1个节点
ListNode * FindFirstCommonNode(ListNode * pHead1,ListNode * pHead2)
{
int len1=GetListLength(pHead1);
int len2=GetListLength(pHead2);
ListNode * longList=pHead1;
ListNode * shortList=pHead2;
int dis=len1-len2;
if(dis<0)
{
dis=len2-len1;
longList=pHead2;
shortList=pHead1;
}
while(dis>0)
{
longList=longList->m_pNext; //长链表先向后走dis步
dis--;
}
//然后2个链表指针一起向后走
while(longList&&shortList&&longList!=shortList)
{
longList=longList->m_pNext;
shortList=shortList->m_pNext;
}
ListNode * result=longList;
return result;
}
欢迎转载,请注明出处,欢迎批评指正,谢谢~.未完待续…