閱讀615 返回首頁    go 阿裏雲 go 技術社區[雲棲]


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 – – x);

(L – – 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)步,之後兩個鏈表同時前進,每次一步,相遇的第一點即為兩個鏈表相交的第一個點。

最後更新:2017-04-03 15:21:46

  上一篇:go JLINK與JTAG的區別
  下一篇:go oracle網絡配置