链表问题

来源:互联网 发布:数据保密协议模板 编辑:程序博客网 时间:2024/04/29 00:14

给定单链表的头指针和一个节点指针,在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);
    }
}

0 0
原创粉丝点击