标签:链表
/************************************************************************/ /* 链表经典练习题 1.从无头链表中删除节点 2.链表逆转 3.判断两个链表是否相交 4.如何检查链表是否存在环 5.求带环链表中环的长度 6.求有环单链表的环连接点位置 7.如果链表可能有环,判断两链表是否相交,并求相交的第一个节点*/ /************************************************************************/
//1.从无头链表中删除节点
void DeleteNode(pNode p)
{
if (NULL == p) //保证p的合法性
{
return;
}
pNode next = p->pNext; //要删除节点的下一个节点
if (next != NULL) //保证待删除节点并非最后一个节点
{
p->data = next->data; //数据域内容覆盖
p->pNext = next->pNext; //删除next指向的节点
delete next;
next = NULL;
}
}//2.链表逆转
void ReverseList(pNode pHead)
{
//仅1个节点的链表直接返回,无需逆转
if (NULL == pHead->pNext || NULL == pHead->pNext->pNext)
{
return;
}
pNode p = pHead->pNext; //扫描指针
pNode pFirst = p; //总是指向链表中第一个有效节点
pNode pTempFirst = p; //记录当前第一个节点地址
p = p->pNext; //扫描指针直接从第2个节点开始
while (p != NULL)
{
pNode tempNext = p->pNext; //暂存当前节点所指的下一个节点地址
pHead->pNext = p; //下面步骤将当前节点插入到第一个节点
p->pNext = pFirst;
pFirst = p; //更新pFirst
p = tempNext; //扫描指针移动
}
pTempFirst->pNext = NULL; //逆转链表最后一个元素收尾
}//3.判断两个链表是否相交
bool IsIntersect(pNode L1, pNode L2)
{
if (NULL == L1 || NULL == L2
|| NULL == L1->pNext
|| NULL == L2->pNext) //头指针非法,或有空链表
{
return false;
}
//遍历L1,让L1指向最后一个节点
while (L1->pNext != NULL)
{
L1 = L1->pNext;
}
//遍历L2,让L2指向最后一个节点
while (L2->pNext != NULL)
{
L2 = L2->pNext;
}
//判断最后的节点是否为同一个
return (L2 == L1);
}
//4.如何检查链表是否存在环
bool IsCircle(pNode pHead)
{
pNode pFast = pHead;
pNode pSlow = pHead;
//如果是不含环单链表,循环以pFast==null或者pFast->pNext==null退出
//如果含环,则循环以pFast==pSlow退出
while (pFast != NULL && pFast->pNext != NULL)
{
pFast = pFast->pNext->pNext; //走两步
pSlow = pSlow->pNext; //走一步
if (pSlow == pFast)
{
break;
}
}
return (pFast == pSlow);
}
//5.求带环链表中环的长度 这个函数并未调用上面的带环函数,是单独写的
int GetCircleLength(pNode pHead)
{
pNode pFast = pHead;
pNode pSlow = pHead;
//循环到第一次相遇则退出
while (pFast != NULL && pFast->pNext != NULL)
{
pFast = pFast->pNext->pNext; //走两步
pSlow = pSlow->pNext; //走一步
if (pSlow == pFast)
{
break;
}
}
if (pSlow != pFast) //无环
{
return 0;
}
//从第一次相遇开始
//环长 = n2 - n1 = 2*n1 - n1 = n1,n1是慢指针走过的节点数
int slowSteps = 0;
do
{
pFast = pFast->pNext->pNext; //走两步
pSlow = pSlow->pNext; //走一步
slowSteps++;
} while (pSlow != pFast);
return slowSteps;
}
//6.求有环单链表的环连接点位置
//这个函数并未调用上面的带环函数,是单独写的
pNode GetConnectionPoint(pNode pHead)
{
pNode pFast = pHead;
pNode pSlow = pHead;
//循环到第一次相遇则退出
while (pFast != NULL && pFast->pNext != NULL)
{
pFast = pFast->pNext->pNext; //走两步
pSlow = pSlow->pNext; //走一步
if (pSlow == pFast)
{
break;
}
}
if (pSlow != pFast) //无环
{
return NULL;
}
//令pFast从头开始走
pFast = pHead;
while (pFast != pSlow)
{
pFast = pFast->pNext;
pSlow = pSlow->pNext;
}
return pFast;
}标签:链表
原文地址:http://blog.csdn.net/a635661820/article/details/44511743