Java_手动实现链表操作

本文介绍了一种双向线性链表的实现方法,包括创建、删除、修改节点值等功能。通过具体示例展示了如何操作链表,如查找特定值的节点、在指定位置插入节点等。

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

/*
 * Author: MengLei
 * Function: 实现双向线性链表:建立,删除,修改值,查找一个节点,查找多个节点,添加,删除等。
 */

public class Temp {
	public static void main(String[] args) {
		Link link = new Link();
		link.createLink(10);	//创建一个拥有10个node的链表
		link.printLink();	//输出:0 --> 1 --> 2 --> 3 --> 4 --> 5 --> 6 --> 7 --> 8 --> 9
		Node foundNode = link.find(8);	//查找值为8的节点
		System.out.println(foundNode);	//输出:Node@c17164。说明返回了一个节点
		foundNode = link.find(18);		//查找值为18的节点
		System.out.println(foundNode);	//输出:null。说明没有找到节点
		link.setNodeValue(2, 5);	//将第三个节点的值改为5
		link.printLink();	//0 --> 1 --> 5 --> 3 --> 4 --> 5 --> 6 --> 7 --> 8 --> 9
		link.append(new Node(99));	//在链表尾部添加一个值为99的节点
		link.printLink();	//输出:0 --> 1 --> 5 --> 3 --> 4 --> 5 --> 6 --> 7 --> 8 --> 9 --> 99
		Link resultLink = link.findAll(18);	//查找所有值为18的节点
		System.out.println(resultLink);	//输出:null。说明没有找到值为18的节点
		resultLink = link.findAll(5);	//查找所有值为18的节点
		System.out.println(resultLink);	//输出:Link@1fb8ee3。说明找到了值为5的节点,并创建了一个新Link用于存储找到的节点(值相同,但与找到的节点不是同一个节点)
		resultLink.printLink();	//输出:5 --> 5
		link.add(2, new Node(88));	//在第三个节点后添加值为88的新节点
		link.printLink();	//输出:0 --> 1 --> 5 --> 88 --> 3 --> 4 --> 5 --> 6 --> 7 --> 8 --> 9 --> 99
		link.delete(3);		//删除第四个节点
		link.printLink();	//输出:0 --> 1 --> 5 --> 3 --> 4 --> 5 --> 6 --> 7 --> 8 --> 9 --> 99
	}
}

class Node {	//节点类
	private int value;
	private Node previous;	//存储前一个节点
	private Node next;	//存储下一个节点
	Node(int value) {	//构造器,需要传入一个int值
		this.value = value;
	}
	public int getValue() {
		return value;
	}
	public void setValue(int value) {
		this.value = value;
	}
	public Node getPrevious() {
		return previous;
	}
	public void setPrevious(Node previous) {
		this.previous = previous;
	}
	public Node getNext() {
		return next;
	}
	public void setNext(Node next) {
		this.next = next;
	}
}

class Link {	//链表类
	private Node head;	//存储头结点
	private Node last;	//存储尾节点
	private int length; //存储链表长度
	public Node getHead() {
		return head;
	}
	public void setHead(Node head) {
		this.head = head;
	}
	public Node getLast() {
		return last;
	}
	public void setLast(Node last) {
		this.last = last;
	}
	public int getLength() {
		return length;
	}
	public void setLength(int length) {
		this.length = length;
	}
	
	public void createLink(int linkLength) {	//建立链表,参数:链表长度
		Node temp = null;	//存储临时节点
		if (linkLength <= 0) {
			System.out.println("Error:链表长度不能小于1!");
		}
		else {
			for (int i=0;i<linkLength;i++) {
				if (i == 0) {	//如果是第一个节点
					this.setHead(new Node(i));	//用i作为节点的值,以便查看建立顺序。
					this.getHead().setPrevious(null);	//这句话其实没有意义,因为head节点的previous节点初始化时就已经是null了。这句话只是为了表明head节点的previous值应该为null。
					temp = this.getHead();
				}
				else {
					Node node = new Node(i);
					temp.setNext(node);
					temp = node;
				}
				if (i == linkLength-1) {
					this.setLast(temp);
					temp.setNext(null);
				}
			}
			this.setLength(linkLength);		//设置链表长度
		}
	}
	
	public void printLink() {	//打印链表
		if (this.getHead() != null) {
			System.out.print(this.getHead().getValue());
			Node temp = this.getHead();
			while (temp.getNext() != null) {
				System.out.print(" --> " + temp.getNext().getValue());
				temp = temp.getNext();				
			}
			System.out.println("");
		}		
	}
	
	public void deleteLink() {	//删除链表
		this.setHead(null);
		this.setLast(null);
		this.setLength(0);
	}
	
	public void setNodeValue(int pos, int value) {	//修改下标为pos的节点的值为value
		if (pos > this.getLength()-1) {
			System.out.println("Error:传入的节点位数大于链表长度!");
		}
		else {
			Node temp = this.getHead();
			for (int i=0;i<pos;i++) {
				temp = temp.getNext();
			}
			temp.setValue(value);
		}
	}
	
	public void append(Node node) {		//在链表尾部添加一个节点
		if (this.getHead() == null && this.getLast() == null) {
			this.setHead(node);
			this.setLast(node);
			node.setNext(null);
			this.setLength(1);
		}
		else {
			this.getLast().setNext(node);
			this.setLast(node);
			node.setNext(null);
			this.setLength(this.getLength()+1);
		}
	}
	
	public void add(int pos, Node node) {	//在下标为pos的位置后添加一个新节点
		if (this.getHead() == null && this.getLast() == null) {
			this.setHead(node);
			this.setLast(node);
			node.setNext(null);
			this.setLength(1);
		}
		else {
			if (pos > this.getLength()-1) {
				System.out.println("Error:传入的节点位数大于链表长度!");
			}
			else {
				Node temp = this.getHead();
				for (int i=0;i<pos;i++) {
					temp = temp.getNext();
				}
				node.setNext(temp.getNext());
				node.setPrevious(temp);
				temp.getNext().setPrevious(node);
				temp.setNext(node);
				this.setLength(this.getLength()+1);
			}
		}
	}
	
	public void delete(int pos) {	//删除下标为pos的节点
		if (this.getHead() == null && this.getLast() == null) {
			System.out.println("Error:链表中没有节点!");
		}
		else {
			if (pos > this.getLength()-1) {
				System.out.println("Error:传入的节点位数大于链表长度!");
			}
			else {
				Node temp = this.getHead();
				for (int i=0;i<pos-1;i++) {
					temp = temp.getNext();
				}
				temp.setNext(temp.getNext().getNext());
				temp.getNext().setPrevious(temp);
				this.setLength(this.getLength()-1);
			}
		}
	}
	
	public Node find(int value) {		//输出值为value的第一个节点
		Node temp = this.getHead();
		if (temp != null) {
			if (temp.getValue() == value)
				return temp;
			else {
				while(temp.getNext() != null) {
					temp = temp.getNext();
					if (temp.getValue() == value)
						return temp;
				}
				return null;
			}			
		}
		else
			return null;
	}
	
	public Link findAll(int value) {	//输出所有值为value的节点,并将所有节点组成一个Link返回
		Link resultLink = new Link();
		Node temp = this.getHead();
		if (temp != null) {
			do {
				if (temp.getValue() == value) {
					resultLink.append(new Node(temp.getValue()));	//这里只能添加与找到的节点值相同的新节点,因为如果添加temp的话,会造成原链表的混乱
				}
				temp = temp.getNext();
			}while(temp.getNext() != null);
			if (resultLink.getHead() == null) {
				return null;
			}
			return resultLink;
		}
		else
			return null;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值