博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java数据结构和算法-5-单链表方法
阅读量:4302 次
发布时间:2019-05-27

本文共 3948 字,大约阅读时间需要 13 分钟。

先了解下什么是链表?通过火车的多节车厢我们来下形容链表。每节车厢都有两个信息,头节点和尾节点,当然有两头我们叫双链表。我们先来看看单向链表,就是链表中节点与节点之间只考虑头节点。

用图来表示一个简单的单向链表。

上面这个图就是一个单链表(list),一个节点(node)中分成两部分,一个用来存储数据,一个是存储下一个节点的内存地址,其实就是指针。根据指针寻找下一个节点,从而找到下一个节点的数据。本篇,我们就来学习一个单链表的基本操作。我们封装的自定义类和方法就是Java JDK中自带的ArrayList的效果。

 

链表基本方法封装

我们需要两个类,一个类Node.java是定义一个节点,结点有数据和指向下一个结点的内存地址。第二个是我们单链表的方法封装,我们先来看看如何插入一个结点的代码实现过程。先理解插入结点代码和打印结点方法的代码,其他删除,插入就变得容易理解。

Node.java内容

package list;/* * 链结点,相当于一个火车车厢 */public class Node {	//数据域	public long data;	//结点域(指针)	public Node next;		public Node(long value) {		this.data = value;	}		/*	 * 显示结点的值	 */	public void display() {		System.out.print(data + " "); //加一个空格,打印效果好看	}}

LinkList.java内容

package list;/* * 链表 相当于火车 */public class LinkList {	//头结点	private Node first;		public LinkList() {		first = null;	}		/*	 * 插入一个结点方法,是在头结点之后插入	 */	public void insertFirst(long value) {		Node node = new Node(value);		node.next = first;		first = node;	}		/*	 * 打印链表结点内容	 */	public void display() {		Node current = first;		while(current != null) {			current.display();			current = current.next;		}		System.out.println();	}}

先看看插入结点的方法,因为我们每次插入都是在新的链表的头结点之后去插入数据。我们这里,暂时不考虑指定结点后面插入结点,我们先每次插入都是在第一个结点之后插入结点。

public void insertFirst(long value) {	Node node = new Node(value);	node.next = first;	first = node;}

第一行是实例化一个Node对象,这个结点的数据值是value, 也就是要把新插入的结点先实例化出来。然后这个新结点指向原来存在的第一个结点。所以上面第二行把first的内存地址赋值给了node.next。第三行,因为插入了新结点,所以把新插入的结点重置为链表的头结点。下面画图来演示一下。

上面图,本来我们头结点是一个32,接下来我们在头结点之后插入一个新结点,就是上面48这个数据,插入之后的效果是这样的:48在32的后边,看箭头顺序来决定前后顺序。

下面看看链表中打印链表的方法代码

public void display() {	Node current = first;	while(current != null) {		current.display();		current = current.next;	}	System.out.println();}

假如当前结点从头结点开始,开始while循环,如果当前结点不为空,就调用结点本身的display()方法,打印这个结点本身的数据。打印完一个结点之后,把当前结点指向下一个结点重置为当前结点,继续判断是否为空和打印。

下面,我们来写一个测试LinkList.java的代码,插入五个结点,并打印结点看看效果。

package list;public class TestLinkList {	public static void main(String[] args) {		LinkList ll = new LinkList();		ll.insertFirst(24);		ll.insertFirst(32);		ll.insertFirst(48);		ll.insertFirst(57);		ll.insertFirst(19);		ll.display();	}}

运行效果

19 57 48 32 24

这个打印效果和对应插入的顺序,确实是每次都在头结点之后插入新结点。

根据上面的基础,我们来写删除结点方法和查找结点方法。

package list;/* * 链表 相当于火车 */public class LinkList {	//头结点	private Node first;		public LinkList() {		first = null;	}		/*	 * 插入一个结点方法,是在头结点之后插入	 */	public void insertFirst(long value) {		Node node = new Node(value);		node.next = first;		first = node;	}		/*	 * 打印链表结点内容	 */	public void display() {		Node current = first;		while(current != null) {			current.display();			current = current.next;		}		System.out.println();	}		/*	 * 查找方法	 */	public Node find(long value) {		// 从头结点开始循环判断		Node current = first;		while(current.data != value) {			// 如果结点中的值不匹配,需要判断当前结点下一个是否为空,如果为空就说明查找不到改数据			if(current.next == null) {				return null; //查找不到			}			// 继续查找下一个节点			current = current.next;		}		//上面把不等于的结点都循环和查找不到情况都写了,剩下退出循环就是要查找的		return current;	}		/*	 * 删除结点,在头结点之后进行删除	 */	public Node deleteFirst() {		Node tmp = first.next;		first.next = tmp.next;		return tmp;	}}

测试类代码

package list;public class TestLinkList {	public static void main(String[] args) {		LinkList ll = new LinkList();		ll.insertFirst(24);		ll.insertFirst(32);		ll.insertFirst(48);		ll.insertFirst(57);		ll.insertFirst(19);		ll.display();				//查找48这个结点		Node node = ll.find(48);		node.display();		System.out.println();		//删除结点		ll.deleteFirst();		ll.display();	}}

测试结果

19 57 48 32 24 48 19 48 32 24

下面继续写一个删除方法,根据data的值去删除这个结点。

/*	 * 删除方法,根据数据来删除结点	 */	public Node delete(long value) {		//当前结点从头结点开始		Node current = first;		//表示当前结点的前面一个结点		Node previous = first;		//删除也是根据查找的逻辑先去找到才能删除		while(current.data != value) {			// 如果结点中的值不匹配,需要判断当前结点下一个是否为空,如果为空就说明查找不到改数据			if(current.next == null) {				return null; //查找不到			}			//找到了就进行删除,删除的逻辑是当前找到这个结点是要删除			//只需要把当前结点前面一个结点.next指向了当前结点后面一个结点			previous = current;			current = current.next;		}				//如果一开始就找到了		if(current == first) {			first = first.next;		}else {			previous.next = current.next;		}		return current;	}

 

转载地址:http://akows.baihongyu.com/

你可能感兴趣的文章
CentOS Docker 安装
查看>>
Nginx
查看>>
Navicat远程连接云主机数据库
查看>>
Nginx配置文件nginx.conf中文详解(总结)
查看>>
Mysql出现Table 'performance_schema.session_status' doesn't exist
查看>>
MySQL innert join、left join、right join等理解
查看>>
vivado模块封装ip/edf
查看>>
sdc时序约束
查看>>
Xilinx Jtag Access/svf文件/BSCANE2
查看>>
NoC片上网络
查看>>
开源SoC整理
查看>>
【2020-3-21】Mac安装Homebrew慢,解决办法
查看>>
influxdb 命令行输出时间为 yyyy-MM-dd HH:mm:ss(年月日时分秒)的方法
查看>>
已知子网掩码,确定ip地址范围
查看>>
判断时间或者数字是否连续
查看>>
docker-daemon.json各配置详解
查看>>
Mac 下docker路径 /var/lib/docker不存在问题
查看>>
Docker(一)使用阿里云容器镜像服务
查看>>
Docker(二) 基础命令
查看>>
Docker(三) 构建镜像
查看>>