题目:
已知一个带有头结点的单链表,结点结构为:
data | link |
在不改变链表的情况下,设计一个尽可能高效的算法,查找链表中倒数第k个结点,若查找成功,输出该结点data的值,并返回1,否则返回0.
分析:
本题的关键是设计一个尽可能高效的算法,通过链表的一遍遍历,找到倒数第k个结点的位置。基本思想:定义两个指针变量,初始时均指向头结点的下一个结点,其中一个指针沿链表移动;当该指针移动到第k个结点时,另一个指针开始与该指针同步移动;当第一个指针移动到链表结尾时,第二个指针所指示的结点即为倒数第k个结点。(本题还可采用两遍遍历、递归算法、辅助数组等实现,但都不是最佳解法)
代码:
#include <stdio.h>
#include <malloc.h>
typedef int ElemType;
typedef struct LNode {
ElemType data;
struct LNode *link;
}LNode, *LinkList;
int Search_k(LinkList list, int k)
{
LinkList p = list->link;
LinkList q = list->link;
int count = 0;
while(p != NULL)
{
if(count < k)
{
count++;
}
else
{
q = q->link;
}
p = p->link;
}
if(count < k)
{
return 0;
}
else
{
printf("%d", q->data);
return 1;
}
}
LinkList CreatList()
{
int x;
LinkList list = (LinkList)malloc(sizeof(LNode));
list->link = NULL;
LNode *s;
LNode *r = list;
scanf("%d", &x);
while(x != EOF)
{
s = (LNode *)malloc(sizeof(LNode));
s->data = x;
r->link = s;
r = s;
scanf("%d", &x);
}
r->link = NULL;
return list;
}
int main()
{
LinkList list;
ElemType k;
list = CreatList();
printf("input the k that you want: ");
scanf("%d", &k);
Search_k(list, k);
return 0;
}
测试结果: