文章目录

  • ​​0 结果![](https://s4.51cto.com/images/blog/202205/25172802_628df6a2dce4b46849.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)​​
  • ​​1 题目​​
  • ​​2 思路​​
  • ​​3 实现​​

0 结果

1 题目

2009年408的算法题_408

2 思路

设q指向末尾第k个结点,p指向最后一个结点(假设为n),那么当k小于等于链表长度时,为p和q结点相差的距离。故有,当p移动k-1个结点后,q再开始移动,当p指向最后一个结点时,q刚好指向倒数第k个结点;如果k大于链表长度,则p指向链表最后一个结点后,q都未曾移动,即指向链表头节点。

例如:1,2,3,4,5,6

求倒数第二个结点,p,q起始都指向头节点,当p移动到结点1时,下次开始p和q开始同步移动,过程如下

p 1 2 3 4 5 6

q 1 2 3 4 5

最后q指向倒数第二个结点。

3 实现

#include <cstdio>
#include <cstdlib>
#include <string.h>
typedef struct node{
char data;
struct node* link;
}NODE;

NODE* func(NODE* L, int k){
NODE *p = L, *q = L;
int cnt = 0;
while(p->link != NULL){
p = p->link;
cnt++;
if(cnt >= k){//当p移动k个结点时,q开始同时指向下一个结点
q = q->link;
}
}
if(q != L){
return q;
}else{
return NULL;
}
}


//使用尾插法创建结点
void create(NODE* &L){
NODE *r = L;
for(int i = 1;i < 7;i++){
NODE* s = (NODE*)malloc(sizeof(NODE));
s->data = i;
r->link = s;
r = s;
}
r->link = NULL;

}
//打印链表
void print(NODE* L){
NODE* p = L->link;
while(p!=NULL){
printf("%d ", p->data);
p = p->link;
}
}

int main(){
NODE *L;
L->link = NULL;
create(L);
int k = 3;
NODE* s = func(L, k);
if(s != NULL){
printf("%d", s->data);
}else{
printf("NULL");
}
return 0;
}