小言_互联网的博客

单链表面试题(百度、腾讯...)

368人阅读  评论(0)

目录

 

学习了单链表的应用(面试题)

1. 求单链表的有效节点

- 思路:

- 代码:

2. 查找单链表倒数第K个节点(新浪面试题)

- 思路

- 代码:

- 备注:

3. 单链表的翻转(腾讯面试题)

- 思路:

- 代码:

- 备注:

4. 从尾到头打印单链表(百度面试题)

- 思路:

- 代码:

- 备注:

5. 合并两个有序单链表,合并之后,依然有序

- 思路:

- 代码:

- 备注:


学习了单链表的应用(面试题)

1. 求单链表的有效节点

- 思路:


  
  1. 1、新增辅助变量num,用于记录单链表有效节点的个数,新增curNode指针,用于遍历单链表的所有节点
  2. 2、num在遍历单链表的所有节点过程中,自增
  3. 3、得出的num即为单链表的有效节点

- 代码:


  
  1. //获的链表的长度
  2. public static int getLength(HeroNode headNode) {
  3. if(headNode == null||headNode.next == null) {
  4. return 0;
  5. }
  6. HeroNode curHeroNode = headNode.next;
  7. int num = 0;
  8. while(curHeroNode!= null) {
  9. num++;
  10. curHeroNode = curHeroNode.next;
  11. }
  12. return num;
  13. }

2. 查找单链表倒数第K个节点(新浪面试题)

- 思路


  
  1. 1、遍历单链表,算出来单链表的长度,记为 length
  2. 2、从头再次遍历单单链表,遍历到第( length - K)个节点时停止,即为倒数第K个节点。

- 代码:


  
  1. //获的倒数第K个节点
  2. private static HeroNode getLastIndexNode(HeroNode headNode, int k) {
  3. if(headNode == null ||headNode.next == null) {
  4. return null;
  5. }
  6. int size = getLength(headNode);
  7. //校验k是否合理
  8. if(k < 0||k > size) {
  9. return null;
  10. }
  11. HeroNode curHeroNode = headNode.next;
  12. for ( int i = 0; i <(size-k) ; i++) { //3-1=2
  13. curHeroNode = curHeroNode.next;
  14. }
  15. // TODO Auto-generated method stub
  16. return curHeroNode;
  17. }

- 备注:

1、别忘了校验下K的合理性

3. 单链表的翻转(腾讯面试题)

- 思路:


  
  1. 1、新添加个头节点,用于盛放翻转后的单链表
  2. reverseHeadNode = new HeroNode();
  3. 2、新创建curNode和nextNode指针,用于指向原链表的节点,用curNode指针遍历单链表,每次遍历的节点,全部插入到reverseHeadNode头节点的后面
  4. 3、遍历完成后,将headNode头节点指向reverseHeadNode. next.

- 代码:


  
  1. //翻转单链表
  2. private static void reverseLinkList(HeroNode headNode) {
  3. //如果链表为空或者只包含一个节点,返回空;
  4. if(headNode.next == null || headNode.next.next == null ) {
  5. return;
  6. }
  7. //定义辅助指针,用来遍历单链表
  8. HeroNode curNode = headNode.next;
  9. HeroNode nextNode = null;
  10. //定义个新头节点,用于盛放翻转后的单链表
  11. HeroNode reverseHeadNode = new HeroNode( 0, "", "");
  12. while(curNode != null) {
  13. nextNode = curNode.next;
  14. curNode.next = reverseHeadNode.next;
  15. reverseHeadNode.next = curNode;
  16. curNode = nextNode;
  17. }
  18. headNode.next = reverseHeadNode.next;
  19. }

- 备注:

1、nextNode指针是必须有的,因为他记录着遍历时下个节点的位置信息(将curNode节点插入到reverseHeadNode节点后,这个节点已经被摘除了,此时只能靠着nextNode节点来继续遍历下个节点)

4. 从尾到头打印单链表(百度面试题)

- 思路:


  
  1. 1、可以先翻转,再打印,但是这样就破坏了原链表的结构(不提倡)
  2. 2、可以应用栈,遍历单链表时,将每个单链表压栈,遍历完成后,再出栈,此时出栈的顺序就是从未到头打印单链表的顺序

- 代码:


  
  1. //单链表翻转打印
  2. private static void reversePrint(HeroNode headNode) {
  3. if(headNode.next == null) {
  4. return;
  5. }
  6. Stack<HeroNode> stack = new Stack<HeroNode>();
  7. HeroNode curNode = headNode.next;
  8. while(curNode != null) {
  9. stack.push(curNode);
  10. curNode = curNode.next;
  11. }
  12. while( stack.size()> 0) {
  13. System.out.println( stack.pop());
  14. }
  15. }

- 备注:

应用栈的先入后出的原理,倒序打印单链表节点信息

5. 合并两个有序单链表,合并之后,依然有序

- 思路:


  
  1. 1、思路一:新建个单链表C,比较前两个单链表的每个节点,节点小的放C尾部
  2. 2、思路二:已其中一个单链表为基准A,让另一个单链表插入A中

- 代码:

思路一的代码:


  
  1. private static SingleLinkList togetherToVerse(HeroNode headNode1, HeroNode headNode2) {
  2. SingleLinkList singleLinkList = new SingleLinkList();
  3. HeroNode headNode3 = singleLinkList.getHeadNode();
  4. // 看两个单链表是否是空
  5. if (headNode1.next == null) {
  6. headNode3.next = headNode2.next;
  7. return singleLinkList;
  8. }
  9. if (headNode2.next == null) {
  10. headNode3.next = headNode1.next;
  11. return singleLinkList;
  12. }
  13. //都不为空的话,同时遍历两个链表,每次比较两个链表的节点,取出最小的元素,排在singleLinkList后面
  14. HeroNode curNode1 = headNode1.next;
  15. HeroNode nextNode1 = null;
  16. HeroNode curNode2 = headNode2.next;
  17. HeroNode nextNode2 = null;
  18. HeroNode curNode3 = headNode3;
  19. while ( true) {
  20. if (curNode1 == null || curNode2 == null) {
  21. break;
  22. }
  23. if (curNode1.getNo() <= curNode2.getNo()) {
  24. System. out.println( "添加了curNode1的数据:" + curNode1.getNo());
  25. nextNode1 = curNode1.next;
  26. curNode1.next = null;
  27. curNode3.next = curNode1;
  28. curNode1 = nextNode1;
  29. // System.out.println("添加了curNode1的数据后下一个数据是:"+curNode1.getNo());
  30. curNode3 = curNode3.next;
  31. } else {
  32. System. out.println( "添加了curNode2的数据:" + curNode2.getNo());
  33. // curNode2 = curNode2.next;
  34. nextNode2 = curNode2.next;
  35. curNode2.next = null;
  36. curNode3.next = curNode2;
  37. curNode2 = nextNode2;
  38. // System.out.println("添加了curNode2的数据后的数据:"+curNode2.getNo());
  39. curNode3 = curNode3.next;
  40. }
  41. }
  42. if (curNode1 == null && curNode2 != null) {
  43. System. out.println( "1");
  44. curNode3.next = curNode2;
  45. }
  46. if (curNode1 != null && curNode2 == null) {
  47. System. out.println( "2");
  48. System. out.println(curNode1.getNo());
  49. curNode3.next = curNode1;
  50. }
  51. return singleLinkList;
  52. }

思路二代码:


  
  1. private static void togetherToVerse1(HeroNode headNode1,HeroNode headNode2) {
  2. if(headNode1.next == null) {
  3. headNode1.next = headNode2.next;
  4. return;
  5. }
  6. if(headNode2.next == null) {
  7. return;
  8. }
  9. HeroNode curNode1 = headNode1.next;
  10. HeroNode preNode1 = headNode1;
  11. HeroNode curNode2 = headNode2.next;
  12. HeroNode nextNode2 = null;
  13. while( true) {
  14. if(curNode1 == null || curNode2 == null) {
  15. break;
  16. }
  17. if(curNode1.getNo() < curNode2.getNo()) {
  18. System. out.println( "curNode1.getNo() < curNode2.getNo()------curNode1:"+curNode1.getNo()+ " "+ "curNode2:"+curNode2.getNo());
  19. preNode1 = curNode1;
  20. curNode1 = curNode1.next;
  21. } else {
  22. System. out.println( "curNode1.getNo() >= curNode2.getNo()------curNode1:"+curNode1.getNo()+ " "+ "curNode2:"+curNode2.getNo());
  23. //插入
  24. nextNode2 = curNode2.next;
  25. curNode2.next = curNode1;
  26. preNode1.next = curNode2;
  27. preNode1 = curNode2;
  28. curNode2 = nextNode2;
  29. }
  30. }
  31. if(curNode1 == null && curNode2 != null) {
  32. preNode1.next = curNode2;
  33. }
  34. }

- 备注:


  
  1. 1、这个代码弄得我蛋疼,切记,同一个节点,千万不能既让单链表一添加,又让链表二添加,否则,链表二的会覆盖链表一的;
  2. 2、当遇到遍历插入的运算是,一定要想到nextNode指针,且不能直接写node = node. next;

转载:https://blog.csdn.net/wangjiaee/article/details/105682958
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场