有关链表的一些常见面试题
2017-06-11 15:14
288 查看
在我们面试的时候链表是考官们比较喜欢考的问题之一,链表总的来说比较简单,但是却比较容易出错,我刚开始接触链表的时候,一不小心就出现了各种各样的问题,因此在这里总结了一些链表有关的面试题。
1.删除一个无头单链表的非尾节点
这里无头单链表并不是真正的无头,只是不告诉我们而已,在做这个题的时候,根据我们的思路,如果要删除一个节点的简单方法就是,把这个节点的前一个节点的next指向后一个节点,然后把这个节点释放掉。这样就删除了一个节点。 但是我们的问题中我们找不到前一个节点,因此我们需要另辟蹊径,我们从题目里面看出删除的是非尾节点,为什么要删除非尾节点?我们从这里入手,画出了这样一个图去解决这个问题:
通过这样的思路就可以解决我们的问题了。有了这样的思路之后我们写代码就变得异常简单了
//删除一个无头单链表的非尾节点 void DelNotTail(ListNode* pos) { ListNode* tmp = pos->next; assert(pos && pos->next); pos->data = tmp->data; pos->next = tmp->next; free(tmp); tmp = NULL; }
2.在无头单链表的一个节点前插入一个节点
有了第一个题的思路,我们是不是可以举一反三呢?既然没办法直接在前面插入一个节点,那么我们在后面插入一个节点,然后交换两个数是不是就可以了。简单吧,想到了这一点,然后我们就可以写出代码了。
//在无头单链表的一个节点前插入一个节点 void InsertFront(ListNode* pos, DataType x) { ListNode* tmp = BuyNode(pos->data); ListNode* next = pos->next; assert(pos && pos->next); pos->next = tmp; tmp->next = next; pos->data = x; }
3.单链表实现约瑟夫环
做这个题首先就要知道什么是约瑟夫环,可以在网上百度一下什么是约瑟夫环(有一个关于约瑟夫环的故事),简单的来讲就是有一个圆环,每次每隔一定间隔释放一个节点,直到最后剩下唯一的一个节点,刚开始拿到这个题,我就被吓住了,让我在纸上画一画还行,让我写代码,感觉好难,但是当我认真的分析了之后发现并不难,因为它是一个环,每次释放掉一个节点之后,可以把前一个节点和后一个节点连接起来,那么**终止条件**是什么?只需要考虑它是一个环,而且最后剩下唯一一个节点,那么终止条件不就是他的下一个节点就是它本身了么?图如下,假设每隔k个节点释放一个节点,最后剩下了一个n
对于每个问题只要我们认真分析之后发现都不难
//在函数外不是一个环 ListNode* JosephRing(ListNode* pList, DataType k) { ListNode* next = pList; ListNode* cur = NULL; while(next->next != NULL) //让单链表成为一个环 { next = next->next; } next->next = pList; next = pList; while(next->next != next) //结束条件是下一个节点是本身 { int count = k; while(--count) { cur = next; next = next->next; } cur->next = next->next; next = next->next; } return cur; }
4.链表逆置
他弄个洋拿到一个问题先分析,对这个题依旧如此,即使第一次我们思考了很久才得出答案,或者都没有得出答案,但是我们思考过了,下次遇到到的时候我们就会有一个印象了。对于这个题,我们可以设置三个指针依次去逆置它,但由于逻辑性要很强,我也不很了解,所以我们采用了另一种方法,通过依次采摘节点的方法;在这样分析了之后我们写出代码
//链表逆置 void Reverse(ListNode** pList) { ListNode* NewList = NULL; ListNode* cur = *pList; if(*pList == NULL || (*pList)->next == NULL) return; while(cur) { ListNode* tmp = cur; //摘节点 cur = cur->next; tmp->next = NewList; NewList = tmp; } PrintList(NewList); }
5.合并有序链表
通过遍历两个链表,每次将较小的结点插入到合并后的新链表。ListNode* MergeList(ListNode* pList1, ListNode* pList2) { ListNode* list = pList1; ListNode* newlist = NULL; //如果有链表为空,直接返回另外一个链表即可 if(pList1 == NULL) PrintList(pList2); else if(pList2 == NULL) PrintList(pList1); //摘一个头节点,选取较小的那个作为新链表的头 if(pList2->data < list->data) { list = pList2; pList2 = pList2->next; } else { list = pList1; pList1 = pList1->next; } newlist = list; //有其中一个链表结束则结束循环 while(pList1 !=NULL && pList2 != NULL) { if(pList1->data <pList2->data) { newlist->next = pList1; newlist = pList1; pList1 = pList1->next; } else { newlist->next = pList2; newlist = pList2; pList2 = pList2->next; } } //直接将剩下的链表链到新链表后 if(pList1 == NULL) newlist->next = pList2; else newlist->next = pList1; return list; }
6.寻找中间节点
设置一个快慢指针,快指针每次走两步,慢指针每次走一步,注意结束条件。ListNode* MidNode(ListNode* pList) { ListNode* slow = pList; ListNode* fast = pList; //链表为空,直接返回空 if(pList == NULL) return NULL; while(fast != NULL &&fast->next != NULL) { fast = (fast->next)->next; slow = slow->next; } return slow; }
7.查找单链表的倒数第k个节点
同样设置一个快慢指针,快指针先走K步,然后同时走,同样注意考虑边界条件ListNode* FindKNode(ListNode* pList, DataType k) { ListNode* slow = pList; ListNode* fast = pList; //链表为空,直接返回空 if(pList == NULL) return NULL; while(k--) { if(fast == NULL)//链表节点少于k个,返回空 return NULL; fast = fast->next; } while(fast) { slow = slow->next; fast = fast->next; } return slow; }
8.这里留下几个稍微难一点的题目,可以思考下
1.判断单链表是否带环?若带环,求环的长度?求环的入口点?并计算每个算法的时间复杂度&空间复杂度。2.判断两个链表是否相交,若相交,求交点。(假设链表不带环)
3.判断两个链表是否相交,若相交,求交点。(假设链表可能带环)【升级版】
4.复杂链表的复制。一个链表的每个节点,有一个指向next指针指向下一个节点,还有一个random指针指向这个链表中的一个随机节点或者NULL,现在要求实现复制这个链表,返回复制后的新链表。
//ps: 复杂链表的结构
struct ComplexNode
{
int _data ; // 数据
struct ComplexNode * _next; // 指向下一个节点的指针
struct ComplexNode * _random; // 指向随机节点(可以是链表中的任意节点 or 空)
};
相关文章推荐
- 数据结构学习笔记 --- 线性表 (一些常见的关于链表的算法和面试题)
- 链表有关的常见面试题
- 数据结构学习笔记 --- 线性表 (一些常见的关于链表的算法和面试题)
- 链表有关的常见面试题
- 链表有关的常见面试题
- 单链表基本操作以及一些常见的面试问题
- 整理一些常见的java及android面试题(1)
- 二级指针的应用-有关链表的一些小题
- 链表基础及常见面试题
- 有关MySQL表类型和一些常见的问题
- 单链表常见面试题
- 链表常见面试题
- 实现了链表的一些常见操作
- SqlServer常见的一些面试题笔记(老鸟勿入)
- 有关iPhone UIDevice UIApplication的一些常见用法
- 关于链表的一些面试题
- 面试收集--关于链表的一些面试题
- 有关iPhone UIDevice UIApplication的一些常见用法
- 想收集一些有关oracle的面试题.
- 常见链表面试题