【数据结构·考研】删除链表中等于给定值val的所有节点

删除链表中等于给定值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;  
} 

运行结果:

猜你喜欢

转载自blog.csdn.net/cjw838982809/article/details/108071647