C语言链表在笔试面试中常考问题总结

1、实现单链表逆置

   无头结点:

1 #include<stdio.h>

 2 #include<stdlib.h>

 3 

 4 typedef struct node{

 5     int data;

 6     struct node *next;

 7 }Node;

 8 

 9 //创建链表

10 Node *CreateList(void){

11     int val,i,n;

12     Node *head,*p,*q;

13 

14     head=NULL;

15     printf("请输入您要建立的链表长度:\n");  

16     scanf("%d",&n);

17     printf("请输入您要输入的数据:\n");  

18     for(i=0;i<n;i++){

19         scanf("%d",&val);

20         p=(Node*)malloc(sizeof(Node));

21         p->data=val;

22         if(head==NULL)

23             head=q=p;

24         else

25             q->next=p;

26         q=p;

27    }

28     p->next=NULL;

29     return head;

30 }

31 

32 //链表的逆置

33 Node *ReverseList(Node *head){

34     Node *p,*q,*r;

35     p=head;

36     q=r=NULL;

37     while(p){

38         q=p->next;

39         p->next=r;

40         r=p;

41         p=q;

42    }

43     return r;

44 }

45 

46 //输出链表

47 void ShowList(Node *head){

48     Node *p;

49     p=head;

50     while(p){

51         printf("%d ",p->data);

52         p=p->next;

53    }

54     printf("\n");

55 }

56 

57 void main(){

58     Node *head;

59 

60     head=CreateList();

61     printf("链表逆置前的数据:\n");

62    ShowList(head);

63 

64     head=ReverseList(head);

65     printf("链表逆置后的数据:\n");  

66    ShowList(head);  

67 }

 

2、判断单链表是否有环

  判断链表是否存在环的办法为:

  设置两个指针(fast,slow),初始值都指向头指针,slow每次前进一步,fast每次前进两步,如果链表存在环,则fast必定先进入环,而slow后进入环,两个指针必定相遇。(当然,fast先行从头到尾部为NULL,则为无环链表)程序如下:

1 #include<stdio.h>

 2 #include<stdlib.h>

 3 

 4 typedef struct node{

 5     int elem;

 6     struct node * next;

 7 }Node, *NodeList;

 8 

9 bool IsExitsLoop(NodeList head){

10     NodeList slow=head,fast=head;

11     while(fast && fast->next){

12         slow=slow->next;

13         fast=fast->next->next;

14         if(slow==fast)

15             break;

16    }

17     return !(fast==NULL || fast->next==NULL);

18 }

19 

20 void main(){

21     //创建一个有环的单链表

22     NodeList head=NULL,p,q;

23     for(int i=1;i<=5;i++){

24         p=(NodeList)malloc(sizeof(Node));

25         p->elem=i;

26         if(head==NULL)

27             head=q=p;

28         else

29             q->next=p;

30         q=p;

31    }

32     p=(NodeList)malloc(sizeof(Node));

33     p->elem=6;

34     q->next=p;

35     q=p;

36     q->next=head->next->next->next;

37     //判断单链表是否存在环

38     printf("单链表是否存在环: ");

39     bool b=IsExitsLoop(head);

40     printf("%s\n",b==false?"false":"true");

41 }

 

3、如果单链表有环,则找到环的入口点

  当fast若与slow相遇时,slow肯定没有遍历完链表,而fast已经在环内循环了n圈(1<=n),假设slow走了s步,而fast走了2s步(fast步数还等于s加上在环上多转的n圈),设环长为r,则:

    2s = s + n*r;

    s = n*r;

设整个链表长为L,入口环与相遇点距离为x,起点到环入口点的距离为a。

    a + x = n*r;

    a + x = (n-1)*r + r = (n-1)*r + L -a;

a = (n-1)r + (L – a – x);

(L – a – x)为相遇点到环入口点的距离,由此可知,从链表头到环入口点等于(n-1)循环内环+相遇点到环入口点,于是我们从链表头、与相遇点分别设一个指针,每次各走一步,两个指针必定相遇,且相遇第一点为环入口点。程序描述如下:

1 #include<stdio.h>

 2 #include<stdlib.h>

 3 

 4 typedef struct node{

 5     int elem;

 6     struct node * next;

 7 }Node, *NodeList;

 8 

 9 //寻找环的入口点

10 NodeList FindLoopPort(NodeList head){

11     NodeList slow=head,fast=head;

12     while(fast && fast->next){

13         slow=slow->next;

14         fast=fast->next->next;

15         if(slow==fast)

16             break;

17    }

18     if(fast==NULL||fast->next==NULL)

19         return NULL;

20     slow=head;

21     while(slow!=fast){

22         slow=slow->next;

23         fast=fast->next;

24    }

25     return slow;

26 }

27 

28 void main(){

29     //创建一个有环的单链表

30     NodeList head=NULL,p,q;

31     for(int i=1;i<=5;i++){

32         p=(NodeList)malloc(sizeof(Node));

33         p->elem=i;

34         if(head==NULL)

35             head=q=p;

36         else

37             q->next=p;

38         q=p;

39    }

40     p=(NodeList)malloc(sizeof(Node));

41     p->elem=6;

42     q->next=p;

43     q=p;

44     q->next=head->next->next->next;

45     //寻找环的入口点

46     NodeList list=FindLoopPort(head);

47     printf("环的入口节点元素值为:%d\n",list->elem);

48 }

 

4、判断两个单链表是否相交,如果相交,给出相交的第一个点(两个链表都不存在环)

  比较好的方法有两个:

  一、将其中一个链表首尾相连,检测另外一个链表是否存在环,如果存在,则两个链表相交,而检测出来的依赖环入口即为相交的第一个点。

  二、如果两个链表相交,那么两个链表从相交点到链表结束都是相同的节点,我们可以先遍历一个链表,直到尾部,再遍历另外一个链表,如果也可以走到同样的结尾点,则两个链表相交。这时我们记下两个链表length,再遍历一次,长链表节点先出发前进(lengthMax-lengthMin)步,之后两个链表同时前进,每次一步,相遇的第一点即为两个链表相交的第一个点。

时间: 2024-09-08 20:52:31

C语言链表在笔试面试中常考问题总结的相关文章

程序员如何快速准备面试中的算法

我决定写篇短文,即为此文.之所以要写这篇文章,缘于微博上常有朋友询问,要毕业找工作了,如何备战算法.尽管在微博上简单梳理过,如下图所示:        但因字数限制,特撰此文着重阐述下:程序员如何快速准备面试中的算法,顺便推荐一些相关的书籍或资料. 备战面试中算法的五个步骤 总体来说,备战面试中的算法,分为五个步骤,如下: 1.首选你得确保自己已经掌握好一门编程语言 如果是C的话,推荐Dennis M. Ritchie & Brian W. Kernighan著的<C程序设计语言>,和

面试中关于Java中涉及到知识点(转)

本篇文章会对面试中常遇到的Java技术点进行全面深入的总结,帮助我们在面试中更加得心应手,不参加面试的同学也能够借此机会梳理一下自己的知识体系,进行查漏补缺.   1. Java中的原始数据类型都有哪些,它们的大小及对应的封装类是什么? (1)boolean boolean数据类型非true即false.这个数据类型表示1 bit的信息,但是它的大小并没有精确定义. <Java虚拟机规范>中如是说:"虽然定义了boolean这种数据类型,但是只对它提供了非常有限的支持.在Java虚拟

[笔试题目] 简单总结笔试和面试中的海量数据问题

        最近在笔试和面试中遇到了很多关于海量数据的问题,在此进行简单的记录,写一篇方便自己下次学习的处理海量数据的文章及在线笔记,同时也希望对你有所帮助.当然,海量数据最出名的还是七月July,但这里我是想直接从实际题目出发,并参考及摘抄了他们那些大牛的文章及自己的想法进行简单总结记录. 一. 原题重现         2015年9月27日百度笔试论述题二选一,其中第一道是关于MapReduce相关的:第二道是搜索引擎中url去重,海量数据集url如何在爬取过程中避免重复爬取过的url.

找工作笔试面试经验总结(C语言基础部分)

2017年9月14号,辞去了在伟易达的工作,怎么说,待了两年了,提辞职不太好说出口,但人各有志,我还是希望能去外面接触更多的东西,也希望能够多认识一些人,丰富我的社交经验. 纵观好几个公司的笔试面试经验,都考得比较简单,笔试和面试不会是那种特别难的题目,基本上都是基础知识,所以我一再告诉我的师弟师妹,出来工作,除了一些比较牛逼的公司出的题比较异类以外,其余的绝大多数公司,考的题目都是比较基础的,所以,基础是非常重要的.下面我就根据我笔试的回忆,考的最多依然是C语言基础,写出以下考到的题目: (1

c语言-在面试中遇到一个枚举类型相关问题

问题描述 在面试中遇到一个枚举类型相关问题 今天在面试中遇到的问题,不知道如何解决enum ADC__enlSRState{ ADC__nReset ADC__nActive ADC__nGetMux2 ADC__nGetMux3 ADC__nGetFuel ADC__nGetTwoPinSensors ADC__nlastState = ADC__nGetTwoPinSensors} 在这里ADC__nlastState起到了什么作用? 解决方案 应该是用在判断一个数值e是否是有效的枚举值的时

Java 面试中的陷阱

自己也面试了很多家公司,觉得这些对今后的学习和工作非常有帮助. 总结的一些知识点非常有代表性.以下是正文. --------------------------------------------------------------------------------------------- 找工作要面试,有面试就有对付面试的办法.以下一些题目来自我和我朋友痛苦的面试经历,提这些问题的公司包括IBM, E*Trade, Siebel, Motorola, SUN, 以及其它大小公司. 面试是没

c语言-关于C语言链表的一些问题,代码怎么都运行不成功跪求大神指点

问题描述 关于C语言链表的一些问题,代码怎么都运行不成功跪求大神指点 下面代码主要实现链表的创建,插入,删除,并且能将两个年龄递增链表进行合并成递减链表 然而在插入和删除操作中gets函数无法起作用,strcmp函数也出现位置冲突报错..功力不足实在解决不了..跪求大神解答..(感觉自己写的东西除了上面两个错误应该还有,但是因为位置冲突问题就只能编译到那个地方无法进行下去..我肉眼实在找不出来.. #include<stdio.h> #include<stdlib.h> #incl

c语言-关于C语言链表学习入门遇到瓶颈

问题描述 关于C语言链表学习入门遇到瓶颈 怎样学习C语言中的链表,有没有什么好的文章博客,详细易懂,发一下链接,谢谢 解决方案 关于链表的学习,我大一的时候也很困惑.特别是当你看着ADT所谓的(抽象数据类型)时.后来我看了一本有源代码的书,结合代码猜发现也不过如此,很简单的.第一,你必须意识到为什么有数组啦,我还要链表呢?这个问题你想想.然后给你个例子,过年回家啦!火车上的座位明显不够啦!这时候火车尾部就会加一节,不行加两节...总之加到,火车头拉不动为止(当然这是玩笑)而如果是数组的话,你就不

问个c语言链表的问题???

问题描述 问个c语言链表的问题??? 不知道我这个链表哪里建立错了,每次编译都通不过. 我觉得原理应该搞懂了,求大神指点一下啊 啊啊啊啊 #include <stdio.h> #include <time.h> #include <stdlib.h> typedef struct link { int a; struct link *next; }ST; ST *begain; ST *p; void creat() { ST *h; srand((unsigned)t