题目:删除链表中等于给定值val的所有节点
思路:非递归的解法,需要一个 pre 指针一直指到 val 值结点的上一个结点。
void listRemove(LinkList& L, int val){
ListNode *p = L, *pre = L;
while(p != NULL){ //p->val等于val
if(p->val == val){
//令s指向p,p向后移动一位并将地址给到pre->next
ListNode* s = p;
p = p->next;
pre->next = p;
delete s; //释放s
}else{ //否则pre与p向后移动
pre = p;
p = p->next;
}
}
}
递归的解法只需要设置一个指针,遍历完这个结点以后,把后续的任务交给下一层来完成,每一层都在删除完 val 结点后直接把上一层的 next 域改为了 val 值结点的下一个结点的地址,完成了删除后的链接。
void listRemove2(LinkList& L, int val){
ListNode* p;
if(L == NULL) return; //递归边界
if(L->val == val){ //p->val等于val
//释放p,任务继续交给新链表L
p = L;
L = L->next;
delete p;
listRemove2(L, val);
}else listRemove2(L->next, val); //不等于val跳过该结点
}
全部代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef struct node{
int val;
struct node* next;
}ListNode,*LinkList;
void listRemove(LinkList& L, int val){
ListNode *p = L, *pre = L;
while(p != NULL){ //p->val等于val
if(p->val == val){
//令s指向p,p向后移动一位并将地址给到pre->next
ListNode* s = p;
p = p->next;
pre->next = p;
delete s; //释放s
}else{ //否则pre与p向后移动
pre = p;
p = p->next;
}
}
}
void listRemove2(LinkList& L, int val){
ListNode* p;
if(L == NULL) return; //递归边界
if(L->val == val){ //p->val等于val
//释放p,任务继续交给新链表L
p = L;
L = L->next;
delete p;
listRemove2(L, val);
}else listRemove2(L->next, val); //不等于val跳过该结点
}
//尾插法
ListNode* createListR(int finish){ //约定以finish结束
int x;
cin >> x;
if(x == finish) return NULL; //递归边界
ListNode* p = new ListNode;
p->val = x;
p->next = createListR(finish); //把剩余的创建任务交给下一层
return p;
}
void printList(ListNode* p){
if(p == NULL) return;
cout<<p->val<<" ";
printList(p->next);
}
int main(){
ListNode* p = createListR(9999);
listRemove(p, 3);
cout<<"双指针:"<<endl;
printList(p);
cout<<endl;
p = createListR(9999);
listRemove2(p, 3);
cout<<"递归:"<<endl;
printList(p);
}
运行结果: