删除链表中等于给定值val的所有节点
备注:链表不带头结点。
思路:非递归的解法,需要一个 pre 指针一直指到 val 值结点的上一个结点。但是考虑到链表没有头结点,所以如果首元结点的值为val,就直接头指针后移,然后释放上一个结点就行。
递归的解法只需要设置一个指针,遍历完这个结点以后,把后续的任务交给下一层来完成,每一层都在删除完 val 结点后直接把上一层的 next 域改为了 val 值结点的下一个结点的地址,完成了删除后的链接。
#include<iostream>
#include<stack>
using namespace std;
//结点定义
typedef struct Node{
int data;
struct Node* next;
}ListNode,*LinkList;
//非递归
void ListRemove1(LinkList& head,int val){
while(head != NULL && head->data == val){
ListNode*s=head;
head = head->next;
delete s;
}
//定义两个指针都指向head
ListNode*p = head,*pre = head;
while(p != NULL){
if(p->data == val){
//如果p->data等于val,先定义一个指针指向它所指的地方
//然后把p下一个结点的地址给pre指针的next域
ListNode*s=p;
p=p->next;
pre->next=p;
//释放s
delete s;
}
else{
//如果p->data并不等于val,pre作为p的前趋,p继续往后走
pre=p;
p=p->next;
}
}
}
//递归
int ListRemove2(LinkList& head,int val){
ListNode*p;
if(head == NULL)
return -1;
if(head->data == val){
p = head;
head = head->next;
delete p;
ListRemove2(head,val);
}
else
ListRemove2(head->next,val);
}
//打印
void printValue(LinkList& head){
if(head != NULL)
cout<<head->data<<" ";
else return;
printValue(head->next);
}
int main(){
//简单定义一个链表 头结点3->3->2->4->3->5
ListNode* head = new ListNode;
head->data = 3;
ListNode* l1 = new ListNode;
l1->data = 3;
head->next = l1;
ListNode* l2 = new ListNode;
l2->data = 2;
l1->next = l2;
ListNode* l3 = new ListNode;
l3->data = 4;
l2->next = l3;
ListNode* l4 = new ListNode;
l4->data = 3;
l3->next = l4;
l4->next = NULL;
ListNode* l5 = new ListNode;
l5->data = 5;
l4->next = l5;
l5->next = NULL;
cout<<"删除前:"<<endl;
printValue(head);
cout<<"删除后:"<<endl;
ListRemove2(head,3);
printValue(head);
//释放
delete head,l1,l2,l3,l4,l5;
}
运行结果: