面试题:输入一个链表,输出该链表中倒数第k个结点。

直接上代码,希望大家喜欢。`

//输入一个链表,输出该链表中倒数第k个结点。
#include<stdio.h>
#include<stdlib.h>
typedef struct Node{
    int data;
    struct Node* next;
}Link; 
Link *createLink(int a[])
{
    Link *head;
    Link *tail,*p;
    head=NULL;
    for(int i=0;i<6;i++)
    {
        p=(Link*)malloc(sizeof(Link));
        p->data=a[i];
        p->next=NULL;
        if(!head)  head=tail=p;
        else
        {
            tail=tail->next=p;
        }
    }
    return head;
}
/*
可行但不高效的常规解法:假设整个链表有n个结点,那么倒数第k个结点就是从头结点开始的第n-k+1个结点。
如果我们能够得到链表中结点的个数n,那我们只要从头结点开始往后走n-k+1步就可以了。那么,
这里的重点就在于如何求链表中节点的个数n,只需要从头开始遍历链表,每经过一个结点,计数器加1就行了。
但是,问题来了:这种思路需要遍历链表两次,第一次统计出链表中结点的个数,第二次才能找到倒数第k个结点。
*/
Link* FindK2(Link *head,int k)
{
    Link *p;
    p=head;
    int count=0; 
    while (count<6-k)
    {
        p=p->next;
        count++;
    }
    return p;
}
/*
可行且高效的解法:为了能够只遍历一次就能找到倒数第k个节点,可以定义两个指针:
  (1)第一个指针从链表的头指针开始遍历向前走k-1,第二个指针保持不动;
  (2)从第k步开始,第二个指针也开始从链表的头指针开始遍历;
  (3)由于两个指针的距离保持在k-1,当第一个(走在前面的)指针到达链表的尾结点时,
        第二个指针(走在后面的)指针正好是倒数第k个结点。
*/
Link* FindK1(Link *head,int k)
{
    if(head == null || k == 0)   return null;
    Link *p1,*p2;
    p1=head;
    p2=NULL;
    for(int i=0;i<k;i++)
    {
        if(p1->next !=NULL)   p1=p1->next;
        else  return null;
    }
    p2=head;
    while(p1)
    {
        p1=p1->next;
        p2=p2->next;
    }

    return p2;
}
int main()
{
    Link *head,*p1,*p2;
    int a[6]={1,2,3,4,5,6};
    head=createLink(a);
    p1=FindK1(head,3);
    p2=FindK2(head,3);
    printf("%d",p1->data);
    printf("%d",p2->data);
    return 0;
}

今日面试题,拿来回忆回忆。

发布了19 篇原创文章 · 获赞 5 · 访问量 7739

猜你喜欢

转载自blog.csdn.net/qq_38119372/article/details/79646493