您的位置:首页 > 其它

链表问题总结

2015-04-06 14:04 246 查看
链表问题总结

//求链表中节点的个数
unsigned int GetLenthList(ListNode * Head)
{
if (Head ==  NULL)
{
return 0;
}
unsigned int length = 0;
ListNode *pCurrent = Head;
while (pCurrent != NULL)
{
length++;
pCurrent = pCurrent->m_pNext;
}
return length;
}
/*                 单链表的反转
* 从头到尾遍历每一个节点,将其摘下放到新链表的最前端,注意链表为空和
* 只有一个节点的情况。时间复杂度为O(n)
*/
ListNode* ReverserList(ListNode* Head)
{
//当链表为空的时候无需反转,直接返回原链表头指针
if (Head == NULL || Head->m_pNext == NULL)
{
return Head;
}
ListNode* pReverserHead = NULL;//翻转后链表的头
ListNode* pCurrent = Head;
while (pCurrent != NULL)
{
listNdoe* pTemp = pCurrent;
pCurrent = pCurrent->m_pNext;
//将当前节点插入到新链表的头
pTemp->m_pNext = pReverserHead ;
pReverserHead = pTemp;
}
return pReverserHead;
}
/*          查找单链表中倒数第K个节点(K>0)
* 思路是使用两个指针 第一个指针在前面走k个节点,然后第二个指针开始走。
* 这样当第一个指针走到最后一个节点的时候,那么第二指针指向的就是倒数第
* k个节点;
**/
ListNode* RGetKNode(ListNode* Head, int k)
{
//k是从1开始的,Head为NULL 表示为空链表
if (k == 0|| Head = nullptr)
{
return NULL;
}
ListNode * First = Head;
ListNdoe *Second = Head;
while (First!=NULL && k-- > 1)
{
First = First->m_pNext;
}
//节点个数小于K返回
if (k>1 || First==NULL)
{
return NULL;
}

while (First->m_pNext != NULL)
{
First = First->m_pNext;
Second = Second->m_pNext;
}
return Second;
}
/*
*        查找链表的中间节点
* 思路:设置两个指针同时向前走,前面的指针一次走2步,后面的指针一次走一步,
* 这样当第一个指针走到最后的时候,第二个指针正好走到中间的位置。注意链表的节点
* 个数为0和1的情况。
**/
ListNode* GetMidNode(ListNode* Head )
{
if (Head == NULL || Head->m_pNext == NULL)
{
return NULL;
}
ListNode * First = Head;
ListNode * Second = Head;
while (First->m_pNext != NULL)
{
First = First->m_pNext;
Second = Second->m_pNext;
if (First->m_pNext != NULL)
{
First = First->m_pNext;
}
}
return Second;
}
/*
*                   从尾到头打印链表
*两种思路: 使用栈,先进后出;使用递归;
**/
//使用栈的方式
void RPrintList(ListNode *Head)
{
std::stack<ListNode *> sList;
ListNdoe* pNode = pHead;
while (pNode != NULL)
{
sList.push(pNode);
pNode = pNode->next;
}
while (!sList.empty())
{
pNode = sList.top();
printf("%d"pNode ->key);
sList.pop();
}
}
//使用递归
void RPintList(ListNode* Head)
{
if (Head == NULL)
{
return;
}
else
{
RPintList(Head->m_pNext);
printf("%d \n",Head->m_pData);
}
}
/*
*    已知链表pHead1和pHead2各自有序,把他们合并成一个链表依然有序
*注意pHead1和phead2各自为空的情况和全为空的情况。
*时间复杂度为O(max(len1 || len2))
**/
ListNode *MergedList(ListNode* pHead1, ListNode* pHead2 )
{
if (pHead2 == NULL)
{
return pHead1;
}
if (pHead1 == NULL)
{
return pHead2;
}
ListNode * MergerList = NULL;
ListNode * MegerListTemp = NULL;
if (pHead1->m_pData < pHead2->m_pData)
{
MergerList = pHead1;
MergerList->m_pNext = nullptr;
MergerList
pHead1 = pHead1->m_pNext;
}
else
{
MergerList = pHead2;
MergerList->m_pNext = NULL;
pHead2 = pHead2->m_pNext;
}
ListNode * MergedListTemp = MergerList;
while (pHead1 ! = NULL && pHead2 != NULL)
{
if (pHead1->m_pData < pHead2->m_pData)
{
MergedListTemp->m_pNext = pHead1;
pHead1 = pHead1->m_pNext;
MergedListTemp = MegerListTemp->m_pNext;
MergedListTemp->m_pNext = NULL;
}
else
{
MergedListTemp->m_pNext = pHead2;
pHead2 = pHead2->m_pNext;
MergedListTemp = MegerListTemp->m_pNext;
MergedListTemp->m_pNext = NULL;
}
}
if (phea1 != NULL)
{
MergedListTemp->m_pNext = pHead1;
}
else if (pHead2 != NULL)
{
MergedListTemp->m_pNext = pHead2
}
return MergerList;
}
//递归算法

ListNode* MergedList(ListNode* pHead1, ListNode pHead2)
{
if (pHead1 == NULL)
{
return pHead2;
}
if (pHead2 == NULL)
{
return pHead2;
}
ListNode *pMergedList = NULL;
if (pHead1->m_pData <pHead2.m_pData)
{
pMergedList = pHead1;
pMergedList->m_pNext = pMergedList(pHead1->m_pNext, pHead2);
}
else
{
pMergedList = pHead2;
pMergedList->m_pNext = pMergedList(pHead1, pHead2.m_pNext);
}
return pMergedList;
}
/*
*            判断一个单链表中是否有环
*   用两个指针去遍历 一个pSlow 一个pFast 如果又环 则一定相遇;
*   就和两个人在操场跑步一样的,如果又环则一定会相遇。
**/
bool HasCircle(ListNode* pHead)
{
ListNode* pSlow = pHead;
ListNode* pFast = pHead;
while (pFast != NULL && pFast->m_pNext != NULL)
{
pFast = pFast->m_pNext->m_pNext;
pSlow = pSlow->m_pNext;
if (pFast == pSlow)
{
return true;
}
}
return false;
}
/*              判断两个单链表是否相交
* 如果两个链表相交,就以为这从相交的点开始,后面的元素是公用的,
* 那么我们只需要判断最后一个元素是否是公用的就可以判定链表是否相交
* 如果判定他是公用的呢? 注意:用地址(指针)!用元素的时候可能会出现巧合;
**/
bool IsIntersected(ListNode *pHead1, ListNode* pHead2)
{
if (pHead2 == NULL || pHead2 == NULL)
{
return false;
}
ListNode* pLast1 = pHead1;
while (pLast1->m_pNext != NULL)
{
pLast1 = pLast1->m_pNext;
}
ListNode* pLast2 = pHead2;
while (pLast2->m_pNext != NULL)
{
pLast2 = pLast2->m_pNext;
}
if (pLast2 == pLast1)
{
return true;
}
else
{
return false;
}
}

/*
*    给出一单链表头指针pHead和一节点指针pToBeDeleted,O(1)时间复杂度删除节点pToBeDeleted
*    这是一道google面试题 如果按照一般的思路就是遍历然后删除那么时间的复杂度就是O(n)
*    注意:既然人家让你这么做,那么肯定就是有解的!我们把他下一个节点的数据复制到该节点,
*    然后删除下一个节点就行了!如果是最后的一个节点那么就只能遍历删除了。
*    平均的时间复杂度仍为O(1);
**/
void DeleteNode(ListNode* pHead, ListNode* pToBeDeleted)
{
if (pToBeDeleted == NULL)
{
return;
}
if ( pToBeDeleted->m_pNext != NULL)
{
pToBeDeleted->m_pData = pToBeDeleted->m_pNext->m_pData;
ListNode * pTemp = pToBeDeleted->m_pNext;
pToBeDeleted->m_pNext = pToBeDeleted->m_pNext->m_pNext;
delete pTemp;
pTemp = NULL;
}
else
{
if (pHead == pToBeDeleted) //只有一个节点;
{
delete pToBeDeleted;
pToBeDeleted = NULL;
pHead = NULL;
}
else
{
ListNode* pNode = pHead;
while (pNode->m_pNext != pToBeDeleted)
{
pNode = pNode->m_pNext;
}
pNode->m_pNext = NULL;
delete pToBeDeleted;
pToBeDeleted = NULL;
}
}
}
/*
*      单链表相交的第一个节点
*可以借鉴前面判断两个但链表是否相交的做法,同时记录两个链表的长度。
*如果list1的长度为len1 ,list2的长度我len2,那么将第一节点先遍历len1-len2个长度
*这样两个节点距离想交节点的距离就相等了。
**/
ListNode* GetFirstComNode(ListNode* Head1, ListNode* Head2)
{
//和前面求链表是否相交相似,就是把len加上去了。
if (pHead1 == NULL || pHead2 == NULL)
{
return NULL;
}
int len1 = 1;
ListNode * pTail = Head1;
while (pTail->m_pNext != NULL)
{
pTail = pTail->m_pNext;
len1++;
}
int len2 = 1;
ListNode * pTail2 = Head2;
while (pTail2->m_pNext != NULL)
{
pTail2 = pTail2->m_pNext;
len2++;
}
if (pTail2 != pTail) //不相交
{
return NULL
}
ListNode* pNode1 = Head1;
ListNode* pNode2 = Head2;
//是他们距离节点的距离相同
if (len1 > len2)
{
int k = len1 - len2;
while (k--)
{
pNode1 = pNode1->m_pNext;
}
}
else
{
int k = len2 - len1;
while (k --)
{
pNode2 = pNode2->m_pNext;
}
}
//判断如果相同的话就返回
while (pNode2 != pNode1)
{
pNode1 = pNode1->m_pNext;
pNode2 = pNode2->m_pNext;
}
return pNode1;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: