面试题15:链表中倒数第k个节点
题目:输入一个链表,输出该连边中倒数第K个结点,为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第一个结点。例如一个连表面有六个结点,从头结点开始它们的值依次是1,2,3,4,5,6.这个链表的倒数第3个结点是值为4的结点。
如图:
控制p1;当p2走到尾,p1刚好就指向结尾第k个元素。
代码如下:
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
typedef struct Node
{
int data;//数据域
struct Node *next;//指向下一个节点的地址
}Node ,*List;//List == Node *
//单链表以NULL结尾
void InitList(List plist)
{
assert(plist != NULL);
if(plist == NULL)
{
return;
}
plist->next = NULL;
}
List BuyNode(int val)
{
Node *p = (Node *)malloc(sizeof(Node));
p->data = val;
//p->next = NULL;
return p;
}
//头插
void Insert_Head(List plist ,int val)
{
Node *p = BuyNode(val);
p->next = plist->next;//4
plist->next = p;//3
}
//从头到尾打印链表
void Show(List plist)
{
Node*p=plist->next;
for( ; p!= NULL ;p=p->next)
{
printf("%d ",p->data);
}
printf("\n");
}
//链表中倒数第k个节点
Node *FindK(List plist,int k )
{
assert(plist != NULL);
Node *p1=plist;
Node *p2=plist;
int i=0;
for( ; ; p2=p2->next)
{
i++;
if(i > k)
{
p1=p1->next;
}
if(p2->next == NULL)
{
return p1;
}
}
if(i<k)
{
throw"error";
}
}
int main()
{
Node plist1;
plist1.next=NULL;
int i=0;
for(i=0; i<10; i++)
{
Insert_Head(&plist1 ,i);
}
Show(&plist1);
Node* p1=FindK(&plist1,3 );
printf("%d \n",p1->data);
Node* p2=FindK(&plist1,5 );
printf("%d \n",p2->data);
Node* p3=FindK(&plist1,6 );
printf("%d \n",p3->data);
return 0;
}
执行结果如下: