一个很多人都曾经被面试过的问题:求链表中的倒数第k个结点。
有不少人在面试之前在网上看到过这个题目,因此知道思路是用两个指针,第一个指针先走k-1步,然后两个指针一起走。当第一个指针走到尾结点时,第二个指针指向的就是倒数第k个结点。于是他大手一挥,写下了下面的代码:
pnode FindKthTotail(pnode head,int k)
{
if(head == NULL)
return NULL;
pnode ahead = head;
pnode behind = NULL;
for(int i=0;i<k-1;i++)
{
ahead = ahead->next;
}
behind = head;
while(ahead->next != NULL)
{
ahead = ahead->next;
behind = behind->next;
}
return behind;
}
写完之后,应聘者看到自己已经判断了输入的指针是不是空指针并作了特殊处理,于是以为这次面试必定能顺利通过,可他没有想到这段代码中仍然有很严重的问题:当链表中的结点总数小于k的时候,程序还是会崩溃。另外,当输入k为0时,同样也会引起程序崩溃。因此,几天之后他收到的仍然不是offer而是拒信。
#include<iostream>
using namespace std;
//定义结点
typedef struct listnode
{
int data;
struct listnode *next;
}node, *pnode;
//链表构建(在头部插入)
pnode insert(pnode head, pnode newnode)
{
newnode->next = head;
head = newnode;
return head;
}
//遍历链表
void output(pnode head)
{
pnode temp = head;
while (temp != NULL)
{
cout<<" "<<temp->data;
temp = temp->next;
}
}
//查看链表中结点个数
int sum_node_num(pnode head)
{
int a = 0;
pnode temp = head;
while(temp!=NULL)
{
a++;
temp = temp->next;
}
return a;
}
//查找链表中倒数第k个结点
pnode FindKthToTail(pnode head,int k)
{
//对链表进行判断,如果为空指针返回空
if (head == NULL)
return NULL;
pnode ahead = head;
pnode behind = NULL;
for (int i = 0; i < k - 1; i++)
{
ahead = ahead->next;
}
behind = head;
while (ahead->next != NULL)
{
ahead = ahead->next;
behind = behind->next;
}
return behind;
}
void main()
{
pnode head = NULL;
int num = 10;
for (int i = 0; i < num; i++)
{
pnode temp = (pnode)malloc(sizeof(node));
temp->data = rand() % 100;
head = insert(head, temp);
}
output(head);
cout << endl;
int a = sum_node_num(head);
cout << a << endl;
//对输入的k进行判断,如果小于结点个数或者为0则提示错误
int k;
cout << "pls input k:";
cin >> k;
if (k > a || k==0)
cout << "error,pls input correct k"<<endl;
else
{
pnode behind = FindKthToTail(head, k);
cout << behind->data << endl;
}
}