链表面试题

1.求单链表中结点的个数

// 求单链表中结点的个数   
unsigned int GetListLength(ListNode * pHead)  
{  
    if(pHead == NULL)  return 0;   
    unsigned int nLength = 0;  
    ListNode * pCurrent = pHead;  
    while(pCurrent != NULL) 
    {
        nLength++; 
        pCurrent = pCurrent->m_pNext; 
    } 
    return nLength; 
} 

2.将单链表反转

// 反转单链表   
ListNode * ReverseList(ListNode * pHead)  
{  
// 如果链表为空或只有一个结点,无需反转,直接返回原链表头指针   
    if(pHead == NULL || pHead->m_pNext == NULL)  
        return pHead;    
    ListNode * pReversedHead = NULL; 
    // 反转后的新链表头指针,初始为NULL   
    ListNode * pCurrent = pHead; 
    while(pCurrent != NULL) 
    { 
        ListNode * pTemp = pCurrent; 
        pCurrent = pCurrent->m_pNext; 
        pTemp->m_pNext = pReversedHead; 
        // 将当前结点摘下,插入新链表的最前端  
        pReversedHead = pTemp; 
    } 
    return pReversedHead; 
} 

3. 查找单链表中的倒数第K个结点(k > 0)

// 查找单链表中倒数第K个结点  
ListNode * RGetKthNode(ListNode * pHead, unsigned int k) 
// 函数名前面的R代表反向  
{  
    if(k == 0 || pHead == NULL) 
// 这里k的计数是从1开始的,若k为0或链表为空返回NULL  
        return NULL;  
   
    ListNode * pAhead = pHead;  
    ListNode * pBehind = pHead;  
    // 前面的指针先走到正向第k个结点  
    while(k > 1 && pAhead != NULL) 
    {  
        pAhead = pAhead->m_pNext;  
        k--;  
    }  
    if(k > 1)     
    // 结点个数小于k,返回NULL  
        return NULL;  
    // 前后两个指针一起向前走,直到前面的指针指向最后一个结点  
    while(pAhead->m_pNext != NULL)  
    {  
        pBehind = pBehind->m_pNext;  
        pAhead = pAhead->m_pNext;  
    }  
    return pBehind;  
// 后面的指针所指结点就是倒数第k个结点  
}

4.查找单链表的中间结点

// 获取单链表中间结点,若链表长度为n(n>0),则返回第n/2+1个结点  
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 != NULL)  
            pAhead = pAhead->m_pNext;  
    }  
    return pBehind; // 后面的指针所指结点即为中间结点  
}

5. 从尾到头打印单链表

// 从尾到头打印链表,使用栈  
void RPrintList(ListNode * pHead)  
{  
    std::stack s;  
    ListNode * pNode = pHead;  
    while(pNode != NULL)  
    {  
        s.push(pNode);  
        pNode = pNode->m_pNext;  
    }  
    while(!s.empty())  
    {  
        pNode = s.top();  
        printf("%d\t", pNode->m_nKey);  
        s.pop();  
    }  
}

使用递归函数

// 从尾到头打印链表,使用递归  
void RPrintList(ListNode * pHead)  
{  
    if(pHead == NULL)  
    {  
        return;  
    }  
    else  
    {  
        RPrintList(pHead->m_pNext);  
        printf("%d\t", pHead->m_nKey);  
    }  
}

6. 已知两个单链表pHead1 和pHead2 各自有序,把它们合并成一个链表依然有序

// 合并两个有序链表  
ListNode * MergeSortedList(ListNode * pHead1, ListNode * pHead2)  
{  
    if(pHead1 == NULL)  
        return pHead2;  
    if(pHead2 == NULL)  
        return pHead1;  
    ListNode * pHeadMerged = NULL;  
    if(pHead1->m_nKey < pHead2->m_nKey)  
    {  
        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_nKey < pHead2->m_nKey)  
        {  
            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;  
}

也有如下递归解法:

ListNode * MergeSortedList(ListNode * pHead1, ListNode * pHead2)  
{  
    if(pHead1 == NULL)  
        return pHead2;  
    if(pHead2 == NULL)  
        return pHead1;  
    ListNode * pHeadMerged = NULL;  
    if(pHead1->m_nKey < pHead2->m_nKey)  
    {  
        pHeadMerged = pHead1;
        pHeadMerged->m_pNext=MergeSortedList(pHead1->m_pNext,pHead2);  
    }  
    else  
    {  
        pHeadMerged = pHead2;  
        pHeadMerged->m_pNext=MergeSortedList(pHead1,pHead2->m_pNext);  
    }  
    return pHeadMerged;  
}

7. 判断一个单链表中是否有环

bool HasCircle(ListNode * pHead)  
{  
    // 快指针每次前进两步
    ListNode * pFast = pHead;
    // 慢指针每次前进一步   
    ListNode * pSlow = pHead;   
    while(pFast != NULL && pFast->m_pNext != NULL)  
    {  
        pFast = pFast->m_pNext->m_pNext;  
        pSlow = pSlow->m_pNext;  
        if(pSlow == pFast) // 相遇,存在环  
            return true;  
    }  
    return false;  
}

你可能感兴趣的:(链表面试题)