给定单链表的头指针和一个节点指针,在O(1)时间内删除该节点
void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted)
{if(!pListHead || !pToBeDeleted)
return;
// 要删除的结点不是尾结点
if(pToBeDeleted->m_pNext != NULL)
{
ListNode* pNext = pToBeDeleted->m_pNext;
pToBeDeleted->m_nValue = pNext->m_nValue;
pToBeDeleted->m_pNext = pNext->m_pNext;
delete pNext;
pNext = NULL;
}
// 链表只有一个结点,删除头结点(也是尾结点)
else if(*pListHead == pToBeDeleted)
{
delete pToBeDeleted;
pToBeDeleted = NULL;
*pListHead = NULL;
}
// 链表中有多个结点,删除尾结点
else
{
ListNode* pNode = *pListHead;
while(pNode->m_pNext != pToBeDeleted)
{
pNode = pNode->m_pNext;
}
pNode->m_pNext = NULL;
delete pToBeDeleted;
pToBeDeleted = NULL;
}
}
无头单链表中删除节点(节点不是第一个也不是最后一个)
void DeleteRandomNode(node* pCurrent)
{
Assert(pCurrent != NULL);
node* pNext = pCurrent -> next;
if(pNext != NULL)
{
pCurrent -> next = pNext -> next;
pCurrent -> data = pNext -> data;
delete pNext;
}
}
单链表就地逆置
方法一
ListNode* ReverseList(ListNode* pHead)
{
ListNode* pReversedHead = NULL;
ListNode* pNode = pHead;
ListNode* pPrev = NULL;
while(pNode != NULL)
{
ListNode* pNext = pNode->m_pNext;
if(pNext == NULL)
pReversedHead = pNode;
pNode->m_pNext = pPrev;
pPrev = pNode;
pNode = pNext;
}
return pReversedHead;
}
方法二
link *swaplink(link *head)
{
link *p,*s;
p=head->next;
head->next=NULL;
while(p!=NULL)
{
s=p->next;
p->next=head->next;
head->next=p;
p=s;
}
return head;
}
链表中倒数第K个节点
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k)
{
if(pListHead == NULL || k == 0)
return NULL;
ListNode *pAhead = pListHead;
ListNode *pBehind = NULL;
for(unsigned int i = 0; i < k - 1; ++ i)
{
if(pAhead->m_pNext != NULL)
pAhead = pAhead->m_pNext;
else
{
return NULL;
}
}
pBehind = pListHead;
while(pAhead->m_pNext != NULL)
{
pAhead = pAhead->m_pNext;
pBehind = pBehind->m_pNext;
}
return pBehind;
}
从尾到头打印链表
不修改原来链表的结构
void PrintListReversingly_Iteratively(ListNode* pHead)
{
std::stack<ListNode*> nodes;
ListNode* pNode = pHead;
while(pNode != NULL)
{
nodes.push(pNode);
pNode = pNode->m_pNext;
}
while(!nodes.empty())
{
pNode = nodes.top();
printf("%d\t", pNode->m_nValue);
nodes.pop();
}
}
当链表较长时,函数调用层次较深,可能导致栈溢出,用栈基于循环鲁棒性较好
void PrintListReversingly_Recursively(ListNode* pHead)
{
if(pHead != NULL)
{
if (pHead->m_pNext != NULL)
{
PrintListReversingly_Recursively(pHead->m_pNext);
}
printf("%d\t", pHead->m_nValue);
}
}