去除链表中所有值为val的值

本文介绍了三种方法来移除链表中所有值等于特定值val的节点,包括不使用虚拟头节点、使用虚拟头节点以及利用链表的递归特性进行操作。提供了对应的Java代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 方法一:不使用虚拟头节点
ListNode.java定义节点类
Main.java主函数
Solution.java定义过滤函数

ListNode.java


public class ListNode {//链表类

    public int val;
    public ListNode next;

    public ListNode(int x) {//构造函数
        val = x;
    }
}

Solution.java

//不使用虚拟头节点
class Solution {

    public ListNode removeElements(ListNode head, int val) {//head是虚拟头节点

        while(head != null && head.val == val){//删除头节点比删除其他节点要麻烦一些,所以单独拿出来写
            ListNode delNode = head;
            head = head.next;
            delNode.next = null;
        }

        if(head == null)//头节点为空意味着链表为空
            return head;

        ListNode prev = head;
        while(prev.next != null){
            if(prev.next.val == val) {
                ListNode delNode = prev.next;
                prev.next = delNode.next;
                delNode.next = null;
            }
            else
                prev = prev.next;
        }

        return head;
    }
}

Main.java

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//为链表赋值
		//--------------------------------------------------------------------------
		System.out.println("请输入链表长度");
		Scanner sc=new Scanner(System.in);
		int length=sc.nextInt();
		System.out.println("请输入链表序列");
		ListNode head=null;
		if(sc.hasNextInt()){
			head=new ListNode(sc.nextInt());
		}
		ListNode temp=head;
		for(int i=1;i<length;i++){
			temp.next=new ListNode(sc.nextInt());
			temp=temp.next;
		}
		//-------------------------------------------------------------------------
		System.out.println("输入要去除的值");
		int val=sc.nextInt();
		Solution solution=new Solution();
		//使用过滤函数
		//-------------------------------------------------------------------------
		ListNode out=solution.removeElements(head, val);//out是输出时的头节点
		System.out.println("输出链表");
		while(out!=null) {
			System.out.print(out.val);
			System.out.print(" ");
			out=out.next;
		}
		
	}

}
  • 方法二:使用虚拟头节点
  • ListNode.java定义节点类
    Main.java主函数

    Solution.java定义过滤函数

 ListNode.java


public class ListNode {//链表类

    public int val;
    public ListNode next;

    public ListNode(int x) {//构造函数
        val = x;
    }
}

Main.java

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		//为链表赋值
		//--------------------------------------------------------------------------
		System.out.println("请输入链表长度");
		Scanner sc=new Scanner(System.in);
		int length=sc.nextInt();
		System.out.println("请输入链表序列");
		ListNode head=null;
		if(sc.hasNextInt()){
			head=new ListNode(sc.nextInt());
		}
		ListNode temp=head;
		for(int i=1;i<length;i++){
			temp.next=new ListNode(sc.nextInt());
			temp=temp.next;
		}
		//-------------------------------------------------------------------------
		
		System.out.println("输入要去除的值");
		int val=sc.nextInt();
		//-------------------------------------------------------------------------
		
		//使用过滤函数
		//-------------------------------------------------------------------------
		//Solution solution=new Solution();//方法一
		Solution2 solution=new Solution2();//方法二
		ListNode out=solution.removeElements(head, val);//out是输出时的头节点
		System.out.println("输出链表");
		while(out!=null) {
			System.out.print(out.val);
			System.out.print(" ");
			out=out.next;
		}
		
	}

}

Solution2.java

//使用虚拟头节点
class Solution2 {

    public ListNode removeElements(ListNode head, int val) {

        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = head;

        ListNode prev = dummyHead;//prev是dummyhead的引用
        while(prev.next != null){
            if(prev.next.val == val)
                prev.next = prev.next.next;//若开头值为要过滤的值,则dummyhead的指向也改变,prev.next即为dummyhead.next
            else							//dummyhead.next=dummyhead.next.next;
                prev = prev.next;//若开头的值无需过滤,则保留原来的开头,dummyhead的指向不变
        }

        return dummyHead.next;//即为新链表的头
    }
}
  • 方法三:利用链表的递归特性
import java.util.Scanner;

//利用链表的递归性质完成对val值的过滤
public class Sum2 {
	//------------------------------------------------------------递归函数--------------------------------------------------------------
		public  static ListNode grep(ListNode head,int value) {//递归函数
			if(head==null) {
				return new ListNode(0);
			}
			else  if(head.val==value){//开头需要删除
				return grep(head.next,value);
			}
			else {//开头不需要删除
				if(head.next!=null) {
					head.next=grep(head.next,value);
				}
				return head;
			}
		}
		
	//-------------------------------------------------------main函数--------------------------------------------------------------
		public static void main(String[] args) {
			
			//为链表赋值
			//--------------------------------------------------------------------------------------------------------------------------------
			System.out.println("请输入链表长度");
			Scanner sc=new Scanner(System.in);
			int length=sc.nextInt();
			System.out.println("请输入链表序列");
			ListNode head=null;
			if(sc.hasNextInt()){
				head=new ListNode(sc.nextInt());
			}
			ListNode temp=head;
			for(int i=1;i<length;i++){
				temp.next=new ListNode(sc.nextInt());
				temp=temp.next;
			}
			
			//输入要去除的值
			//-----------------------------------------------------------------------------------------------------------------------------------
			
			System.out.println("输入要去除的值");
			int val=sc.nextInt();
			
			//使用过滤函数
			//---------------------------------------------------------------------------------------------------------------------------------
			ListNode out=grep(head,val);
			
			//输出链表
			//---------------------------------------------------------------------------------------------------------------------------------
			System.out.println("输出链表");
			while(out!=null) {
				System.out.print(out.val);
				System.out.print(" ");
				out=out.next;
			}
		}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值