链表常见题总结一
2016-08-09 21:51
204 查看
链表可以说是笔试面试的重点,因为写一个链表相关的题可以在短时间写出来,并且考验测试人的水平。特别将平时经常做的链表的题拿上来,做个小结。
1. 求单链表中结点的个数
2. 将单链表反转
3. 查找单链表中的倒数第K个结点(k > 0)
4. 查找单链表的中间结点
5. 已知两个单链表pHead1 和pHead2 各自有序,把它们合并成一个链表依然有序
6. 判断一个单链表中是否有环
7. 判断两个单链表是否相交
8. 求两个单链表相交的第一个节点
9. 已知一个单链表中存在环,求进入环中的第一个节点
10. 给出一单链表头指针pHead和一节点指针pToBeDeleted,O(1)时间复杂度删除节点pToBeDeleted
ListNode* TheKthListNode(ListNode* phead,int k)
{
ListNode *fast = phead;
int i = 0;
while (i < k-1 && fast != NULL)
{
fast = fast->pnext;
i++;
}
if (fast == NULL)
return NULL;
ListNode *slow = phead;
while (fast->pnext != NULL)
{
slow = slow->pnext;
fast = fast->pnext;
}
slow->pnext = NULL;
return slow;
}
文中均为自己写的代码,均通过自己写的简单的测试,但是肯定还有些测试不能通过,希望有人找出错误给我纠正一下,不胜感谢。待更新ing..
1. 求单链表中结点的个数
2. 将单链表反转
3. 查找单链表中的倒数第K个结点(k > 0)
4. 查找单链表的中间结点
5. 已知两个单链表pHead1 和pHead2 各自有序,把它们合并成一个链表依然有序
6. 判断一个单链表中是否有环
7. 判断两个单链表是否相交
8. 求两个单链表相交的第一个节点
9. 已知一个单链表中存在环,求进入环中的第一个节点
10. 给出一单链表头指针pHead和一节点指针pToBeDeleted,O(1)时间复杂度删除节点pToBeDeleted
1.求单链表节点的个数
//求单链表中结点的个数 int Length(ListNode *phead) { int len = 0; while (phead != NULL) { len++; phead = phead->pnext; } return len; }
2.单链表反转
我是按照递归和非递归做的//单链表反转 ListNode* Reverse(ListNode *phead) { if (phead == NULL||phead->pnext==NULL) return phead; ListNode *pre = new ListNode(0); ListNode *temp = pre; pre->pnext = phead; ListNode* cur = phead; ListNode* next = phead->pnext; while (next != NULL) { cur->pnext = pre; pre = cur; cur = next; next = next->pnext; } cur->pnext = pre; phead->pnext = NULL; delete temp; return cur; } //单链表反转,递归 ListNode* ReverseRecursion(ListNode* phead) { if (phead == NULL || phead->pnext == NULL) return phead; ListNode *temp = phead->pnext; ListNode *newhead=ReverseRecursion(temp); //先反转链表结点的后一个结点 temp->pnext = phead; //将该结点放在其原来后面结点的后一个结点 phead->pnext = NULL; return newhead; }
3.倒数第K个节点
//查找单链表中的倒数第K个结点(K>0),采用双指针法ListNode* TheKthListNode(ListNode* phead,int k)
{
ListNode *fast = phead;
int i = 0;
while (i < k-1 && fast != NULL)
{
fast = fast->pnext;
i++;
}
if (fast == NULL)
return NULL;
ListNode *slow = phead;
while (fast->pnext != NULL)
{
slow = slow->pnext;
fast = fast->pnext;
}
slow->pnext = NULL;
return slow;
}
4.查找单链表的中间节点
//找出单链表的中间结点,采用快慢指针 ListNode* MiddleNode(ListNode* phead) { ListNode *slow = phead; ListNode *fast = phead; if (phead == NULL) return phead; while (fast->pnext != NULL) { fast = fast->pnext; slow = slow->pnext; if (fast->pnext != NULL) fast = fast->pnext; } return slow; }
5.合并两个有序的链表,使得结果仍然有序
//两链表各自有序,合并成一个链表依然有序 ListNode* Merge(ListNode *phead1, ListNode *phead2) { if (phead1 == NULL) return phead1; if (phead2 == NULL) return phead2; ListNode *pre=new ListNode(0); ListNode *cur = pre; ListNode *temp = NULL; while (phead1 && phead2) { temp = phead1->val < phead2->val ? phead1 : phead2; cur->pnext = temp; cur = temp; if (temp == phead1) phead1 = phead1->pnext; else phead2 = phead2->pnext; } while (phead1) { cur->pnext = phead1; cur = cur->pnext; phead1 = phead1->pnext; } while (phead2) { cur->pnext = phead2; cur = cur->pnext; phead2 = phead2->pnext; } cur->pnext = NULL; temp = pre->pnext; delete pre; return temp; }
6.判断单链表是否有环
//判断一个单链表是否有环,同样采用快慢指针,要是他们重合就有环 bool IsCircle(ListNode *phead) { ListNode *fast = phead; ListNode *slow = phead; while (fast!=NULL && fast->pnext!=NULL) { fast = fast->pnext->pnext; slow = slow->pnext; if (fast == slow) return true; } return false; }
7.判断两个单链表是否相交
//判断两个单链表是否相交,若相交,则两个链表的最后一个节点必定相同,否则不相交 bool IsConnect(ListNode *phead1, ListNode *phead2) { if (phead1 == NULL || phead2 == NULL) { return false; } while (phead1->pnext != NULL) { phead1 = phead1->pnext; } while (phead2->pnext != NULL) { phead2 = phead2->pnext; } if (phead1 == phead2) return true; else return false; }
8.求两个链表相交的第一个节点
//求两个单链表相交的第一个节点,先分别计算两个链表的长度,再让长的链表先走超出的那部分,然后两个链表步调相同 ListNode* TheFirstConnectNode(ListNode *phead1, ListNode *phead2) { if (phead1 == NULL || phead2 == NULL) { return NULL; } ListNode *temp1 = phead1; ListNode *temp2 = phead2; int len1 = 0, len2 = 0; while (temp1->pnext != NULL) { len1++; temp1 = temp1->pnext; } while (temp2->pnext != NULL) { len2++; temp2 = temp2->pnext; } if (temp1 != temp2) return NULL; else { if (len1 > len2) { temp1 = phead1; for (int i = 0; i < len1 - len2;i++) { temp1 = temp1->pnext; } temp2 = phead2; } else { temp2 = phead2; for (int i = 0; i < len2 - len1; i++) { temp2 = temp2->pnext; } temp1 = phead1; } while (temp1 != temp2) { temp1 = temp1->pnext; temp2 = temp2->pnext; } return temp1; } }
9.已知单链表有环,求进入环中的第一个节点
//已知单链表有环,求进入环中的第一个节点 ListNode *TheFirstCircleNode(ListNode *phead) { //先找一个在环中的节点,采用快慢指针 ListNode *fast = phead->pnext->pnext; ListNode *slow = phead->pnext; while (fast != slow) { slow = slow->pnext; fast = fast->pnext->pnext; } //计算环的长度 int len = 1; fast = fast->pnext; while (fast!=slow) { len++; fast = fast->pnext; } //让一个快指针先走len,然后慢指针开始走,当两个第一次相遇点就是环的第一个节点 fast = phead; slow = phead; for (int i = 0; i < len; i++) { fast = fast->pnext; } while (fast != slow) { fast = fast->pnext; slow = slow->pnext; } slow->pnext = NULL; //此处只是为了提炼一个节点出来,免得打印的时候因为是循环,打印循环输出一满屏 return slow; }
10.删除一个指定节点,时间复杂度为O(1)
//给出一单链表头指针和一节点指针toBeDel,O(1)时间复杂度删除节点toBeDel void DelOneNode(ListNode *phead, ListNode *toBeDel) { if (toBeDel->pnext == NULL) { toBeDel = NULL; } toBeDel->val = toBeDel->pnext->val; //O(1)时间复杂度的话只能将后面节点的值赋给该结点,在将 toBeDel->pnext = toBeDel->pnext->pnext; //要删除的节点的后一个节点删除; }
文中均为自己写的代码,均通过自己写的简单的测试,但是肯定还有些测试不能通过,希望有人找出错误给我纠正一下,不胜感谢。待更新ing..
相关文章推荐
- 【leetcode】链表常见题目总结
- 常见链表面试题的总结
- 链表的一些常见笔试面试问题总结及代码
- 【数据结构】链表的原理及与其相关的常见面试题总结
- Java 链表常见考题总结
- 【数据结构】链表的原理及与其相关的常见面试题总结
- 数据结构——链表(面试常见题型总结)
- 单链表常见笔试面试题总结
- C++链表操作总结和常见链表操作
- 常见的链表题目总结
- 链表类常见算法题总结
- Php部分常见问题总结第1/2页
- CrystalReport开发常见错误总结
- JfreeChart使用经验总结(分析了使用中碰到的一些常见问题)
- [原创]Loadruner常见问题解决总结
- 开发与测试常见问题总结与建议
- Sql常见面试题(总结)
- 【转】SQL SERVER中一些常见性能问题的总结
- SQL SERVER中一些常见性能问题的总结(转载)
- SQL SERVER中一些常见性能问题的总结