链表面试题

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<ListNode *> 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;  
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 转载请注明出处:http://www.jianshu.com/p/c65d9d753c31 在上一篇博客《数据结构...
    Alent阅读 3,541评论 4 74
  • 链表面试题积累 输入一个带头结点的链表。反转链表并返回头节点 注意边界条件控制 编码之前注意分析需求的内容。不要边...
    沧州宁少阅读 392评论 0 1
  • 【声明】欢迎转载,但请保留文章原始出处→_→文章来源:http://www.jianshu.com/p/08d08...
    梦工厂阅读 3,788评论 3 31
  • 记得小时候,看得最多的除了书,就是抗战的电影。《地道战》、《地雷战》、《小兵张嘎》……因此,心里一直怀有一种精忠报...
    墨晓言阅读 607评论 0 0
  • 这些日子审视自己,这么多年来都不曾努力过,小时候凭着几分读书的天赋没怎么努力成绩也是排在前面,一路顺利直到中考考了...
    宇凡谦谦阅读 392评论 2 5