题目
思路1
暴力法
-
删除倒数第n个结点就是删除正数第len-n个结点。
-
先扫描一遍链表计算长度len。
-
再遍历链表,删除第len-n个结点(找到删除结点的前缀,然后删除)
#include<stdio.h>
#include<stdlib.h>
//定义链表结点结构体
typedef struct LinkNode{
int val;
struct LinkNode *next;
}LinkNode;
//创建链表
LinkNode *creatLinked(){
LinkNode *L=(LinkNode*)malloc(sizeof(LinkNode));
L->next=NULL;
LinkNode *rail=L;//尾指针
int val;
while(1){
scanf("%d",&val);
if(val!=-1){
LinkNode *s=(LinkNode*)malloc(sizeof(LinkNode));
s->val=val;
s->next=NULL;
rail->next=s;
rail=s;//尾插法,正序
}else
break;
}
return L;
}
//打印链表
void printList(LinkNode *L){
while(L){
printf("%d ",L->val);
L=L->next;
}
}
//删除倒数第n个结点
LinkNode *remove(LinkNode *head,int k){
int cnt=0,l,i=1;
LinkNode *p=head,*q;
while(p){
p=p->next;
cnt++;
}//求出链表总长度
p=head->next;
while(p){
if(i==cnt-k-1){
q=p->next;//给q指针赋值
p->next=q->next;
free(q);
break;
}else{
p=p->next;
i++;
}
}
return head->next;
}
int main(){
LinkNode *L=creatLinked();//创建结点
LinkNode *head=remove(L,2);
printList(head);
return 0;
}
思路2
优解:快慢指针法
-
定义快指针和慢指针fast和slow,初始都指向头结点。
-
让快指针先走n+1步
-
然后慢指针和快指针同时向后走,当快指针走到链表最后时,慢指针就指向删除结点的前缀,就可以删除了。
#include<stdio.h>
#include<stdlib.h>
//定义链表结点结构体
typedef struct LinkNode{
int val;
struct LinkNode *next;
}LinkNode;
//创建链表
LinkNode *creatLinked(){
LinkNode *L=(LinkNode*)malloc(sizeof(LinkNode));
L->next=NULL;
LinkNode *rail=L;//尾指针
int val;
while(1){
scanf("%d",&val);
if(val!=-1){
LinkNode *s=(LinkNode*)malloc(sizeof(LinkNode));
s->val=val;
s->next=NULL;
rail->next=s;
rail=s;//尾插法,正序
}else
break;
}
return L;
}
//打印链表
void printList(LinkNode *L){
while(L){
printf("%d ",L->val);
L=L->next;
}
}
//删除链表倒数第n个结点
LinkNode *remove(LinkNode *head,int k){
LinkNode *fast=head,*slow=head;
k=k+1;
while(k>0){
fast=fast->next;
k--;
}
while(fast){
slow=slow->next;
fast=fast->next;
}
LinkNode *p=slow->next;
slow->next=p->next;
delete p;
return head->next;
}
int main(){
LinkNode *L=creatLinked();//创建结点
LinkNode *head=remove(L,2);
printList(head);
return 0;
}