c语言面试题重点整理·单链表操作

来源:互联网 发布:淘宝摄影服务市场入驻 编辑:程序博客网 时间:2024/06/07 16:12


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

// 求单链表中结点的个数   2 unsigned int GetListLength(ListNode * pHead)   3 {   4     if(pHead == NULL)   5         return 0;   6    7     unsigned int nLength = 0;   8     ListNode * pCurrent = pHead;   9     while(pCurrent != NULL)  10     {  11         nLength++;  12         pCurrent = pCurrent->m_pNext;  13     }  14     return nLength;  15 }  

2. 将单链表反转

1 // 反转单链表   2 ListNode * ReverseList(ListNode * pHead)   3 {   4         // 如果链表为空或只有一个结点,无需反转,直接返回原链表头指针   5     if(pHead == NULL || pHead->m_pNext == NULL)     6         return pHead;   7    8     ListNode * pReversedHead = NULL; // 反转后的新链表头指针,初始为NULL   9     ListNode * pCurrent = pHead;  10     while(pCurrent != NULL)  11     {  12         ListNode * pTemp = pCurrent;  13         pCurrent = pCurrent->m_pNext;  14         pTemp->m_pNext = pReversedHead; // 将当前结点摘下,插入新链表的最前端  15         pReversedHead = pTemp;  16     }  17     return pReversedHead;  18 } 

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


 1 // 查找单链表中倒数第K个结点   2 ListNode * RGetKthNode(ListNode * pHead, unsigned int k) // 函数名前面的R代表反向   3 {   4     if(k == 0 || pHead == NULL) // 这里k的计数是从1开始的,若k为0或链表为空返回NULL   5         return NULL;   6    7     ListNode * pAhead = pHead;   8     ListNode * pBehind = pHead;   9     while(k > 1 && pAhead != NULL) // 前面的指针先走到正向第k个结点  10     {  11         pAhead = pAhead->m_pNext;  12         k--;  13     }  14     if(k > 1)     // 结点个数小于k,返回NULL  15         return NULL;  16     while(pAhead->m_pNext != NULL)  // 前后两个指针一起向前走,直到前面的指针指向最后一个结点  17     {  18         pBehind = pBehind->m_pNext;  19         pAhead = pAhead->m_pNext;  20     }  21     return pBehind;  // 后面的指针所指结点就是倒数第k个结点  22 } 

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

 // 获取单链表中间结点,若链表长度为n(n>0),则返回第n/2+1个结点   2 ListNode * GetMiddleNode(ListNode * pHead)   3 {   4     if(pHead == NULL || pHead->m_pNext == NULL) // 链表为空或只有一个结点,返回头指针   5         return pHead;   6    7     ListNode * pAhead = pHead;   8     ListNode * pBehind = pHead;   9     while(pAhead->m_pNext != NULL) // 前面指针每次走两步,直到指向最后一个结点,后面指针每次走一步  10     {  11         pAhead = pAhead->m_pNext;  12         pBehind = pBehind->m_pNext;  13         if(pAhead->m_pNext != NULL)  14             pAhead = pAhead->m_pNext;  15     }  16     return pBehind; // 后面的指针所指结点即为中间结点  17 }  
5. 从尾到头打印单链表

1 // 从尾到头打印链表,使用栈   2 void RPrintList(ListNode * pHead)   3 {   4     std::stack<ListNode *> s;   5     ListNode * pNode = pHead;   6     while(pNode != NULL)   7     {   8         s.push(pNode);   9         pNode = pNode->m_pNext;  10     }  11     while(!s.empty())  12     {  13         pNode = s.top();  14         printf("%d\t", pNode->m_nKey);  15         s.pop();  16     }  17 } 

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

 // 合并两个有序链表   2 ListNode * MergeSortedList(ListNode * pHead1, ListNode * pHead2)   3 {   4     if(pHead1 == NULL)   5         return pHead2;   6     if(pHead2 == NULL)   7         return pHead1;   8     ListNode * pHeadMerged = NULL;   9     if(pHead1->m_nKey < pHead2->m_nKey)  10     {  11         pHeadMerged = pHead1;  12         pHeadMerged->m_pNext = NULL;  13         pHead1 = pHead1->m_pNext;  14     }  15     else  16     {  17         pHeadMerged = pHead2;  18         pHeadMerged->m_pNext = NULL;  19         pHead2 = pHead2->m_pNext;  20     }  21     ListNode * pTemp = pHeadMerged;  22     while(pHead1 != NULL && pHead2 != NULL)  23     {  24         if(pHead1->m_nKey < pHead2->m_nKey)  25         {  26             pTemp->m_pNext = pHead1;  27             pHead1 = pHead1->m_pNext;  28             pTemp = pTemp->m_pNext;  29             pTemp->m_pNext = NULL;  30         }  31         else  32         {  33             pTemp->m_pNext = pHead2;  34             pHead2 = pHead2->m_pNext;  35             pTemp = pTemp->m_pNext;  36             pTemp->m_pNext = NULL;  37         }  38     }  39     if(pHead1 != NULL)  40         pTemp->m_pNext = pHead1;  41     else if(pHead2 != NULL)  42         pTemp->m_pNext = pHead2;  43     return pHeadMerged;  44 } 

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

bool HasCircle(ListNode * pHead)   2 {   3     ListNode * pFast = pHead; // 快指针每次前进两步   4     ListNode * pSlow = pHead; // 慢指针每次前进一步   5     while(pFast != NULL && pFast->m_pNext != NULL)   6     {   7         pFast = pFast->m_pNext->m_pNext;   8         pSlow = pSlow->m_pNext;   9         if(pSlow == pFast) // 相遇,存在环  10             return true;  11     }  12     return false;  13 }  

8. 判断两个单链表是否相交

bool IsIntersected(ListNode * pHead1, ListNode * pHead2)   2 {   3         if(pHead1 == NULL || pHead2 == NULL)   4                 return false;   5    6     ListNode * pTail1 = pHead1;   7     while(pTail1->m_pNext != NULL)   8         pTail1 = pTail1->m_pNext;   9   10     ListNode * pTail2 = pHead2;  11     while(pTail2->m_pNext != NULL)  12         pTail2 = pTail2->m_pNext;  13     return pTail1 == pTail2;  14 } 

9. 求两个单链表相交的第一个节点

ListNode* GetFirstCommonNode(ListNode * pHead1, ListNode * pHead2)   2 {   3     if(pHead1 == NULL || pHead2 == NULL)   4         return NULL;   5    6     int len1 = 1;   7     ListNode * pTail1 = pHead1;   8     while(pTail1->m_pNext != NULL)   9     {  10         pTail1 = pTail1->m_pNext;  11         len1++;  12     }  13   14     int len2 = 1;  15     ListNode * pTail2 = pHead2;  16     while(pTail2->m_pNext != NULL)  17     {  18         pTail2 = pTail2->m_pNext;  19         len2++;  20     }  21   22     if(pTail1 != pTail2) // 不相交直接返回NULL  23         return NULL;  24   25     ListNode * pNode1 = pHead1;  26     ListNode * pNode2 = pHead2;  27         // 先对齐两个链表的当前结点,使之到尾节点的距离相等  28     if(len1 > len2)  29     {  30         int k = len1 - len2;  31         while(k--)  32             pNode1 = pNode1->m_pNext;  33     }  34     else  35     {  36         int k = len2 - len1;  37         while(k--)  38             pNode2 = pNode2->m_pNext;  39     }  40     while(pNode1 != pNode2)  41     {  42         pNode1 = pNode1->m_pNext;  43         pNode2 = pNode2->m_pNext;  44     }  45         return pNode1;  46 } 

10. 已知一个单链表中存在环,求进入环中的第一个节点

 ListNode* GetFirstNodeInCircle(ListNode * pHead)   2 {   3     if(pHead == NULL || pHead->m_pNext == NULL)   4         return NULL;   5    6     ListNode * pFast = pHead;   7     ListNode * pSlow = pHead;   8     while(pFast != NULL && pFast->m_pNext != NULL)   9     {  10         pSlow = pSlow->m_pNext;  11         pFast = pFast->m_pNext->m_pNext;  12         if(pSlow == pFast)  13             break;  14     }  15     if(pFast == NULL || pFast->m_pNext == NULL)  16         return NULL;  17   18     // 将环中的此节点作为假设的尾节点,将它变成两个单链表相交问题  19     ListNode * pAssumedTail = pSlow;   20     ListNode * pHead1 = pHead;  21     ListNode * pHead2 = pAssumedTail->m_pNext;  22   23     ListNode * pNode1, * pNode2;  24     int len1 = 1;  25     ListNode * pNode1 = pHead1;  26     while(pNode1 != pAssumedTail)  27     {  28         pNode1 = pNode1->m_pNext;  29         len1++;  30     }  31       32     int len2 = 1;  33     ListNode * pNode2 = pHead2;  34     while(pNode2 != pAssumedTail)  35     {  36         pNode2 = pNode2->m_pNext;  37         len2++;  38     }  39   40     pNode1 = pHead1;  41     pNode2 = pHead2;  42     // 先对齐两个链表的当前结点,使之到尾节点的距离相等  43     if(len1 > len2)  44     {  45         int k = len1 - len2;  46         while(k--)  47             pNode1 = pNode1->m_pNext;  48     }  49     else  50     {  51         int k = len2 - len1;  52         while(k--)  53             pNode2 = pNode2->m_pNext;  54     }  55     while(pNode1 != pNode2)  56     {  57         pNode1 = pNode1->m_pNext;  58         pNode2 = pNode2->m_pNext;  59     }  60     return pNode1;  61 } 

11. 给出一单链表头指针pHead和一节点指针pToBeDeleted,O(1)时间复杂度删除节点pToBeDeleted

void Delete(ListNode * pHead, ListNode * pToBeDeleted)   2 {   3     if(pToBeDeleted == NULL)   4         return;   5     if(pToBeDeleted->m_pNext != NULL)   6     {   7         pToBeDeleted->m_nKey = pToBeDeleted->m_pNext->m_nKey; // 将下一个节点的数据复制到本节点,然后删除下一个节点   8         ListNode * temp = pToBeDeleted->m_pNext;   9         pToBeDeleted->m_pNext = pToBeDeleted->m_pNext->m_pNext;  10         delete temp;  11     }  12     else // 要删除的是最后一个节点  13     {  14         if(pHead == pToBeDeleted) // 链表中只有一个节点的情况  15         {  16             pHead = NULL;  17             delete pToBeDeleted;  18         }  19         else  20         {  21             ListNode * pNode = pHead;  22             while(pNode->m_pNext != pToBeDeleted) // 找到倒数第二个节点  23                 pNode = pNode->m_pNext;  24             pNode->m_pNext = NULL;  25             delete pToBeDeleted;  26         }     27     }  28 }

0 0
原创粉丝点击