数据结构之单链表(基于Java实现)
链表:在计算机中用一组任意的存储单元存储线性表的数据元素称为链式存储结构,这组存储结构可以是连续的,也可以是不连续的,因此在存储数据元素时可以动态分配内存。
注:在java中没有指针的概念,可以理解为对象的引用。
单链表的特点是链表的方向是单向的,对链表的访问要通过顺序读取,从头部开始。单链表是由一个个节点(Node)组装起来的,其中每个节点都由成员变量指向下一个节点。
特点概述:
每个节点由数据域和指针域组成
比顺序结构存储密度小。链式存储结构中每个节点都由数据域和指针域两部分组成,相比顺序结构增加了存储空间
逻辑上相邻的两个节点物理位置不必相邻
插入,删除灵活
查找节点时链式存储结构要比顺序结构慢
Java中链表的定义如下:
class Node<T>{
E data;
Node<E> next;
}
基于Java,来探究一下链表的原理:
首先,写一段简单的代码
public class Node <T>{
private T v;
Node<T> next;
public static void main(String[] args){
Node node3 = new Node();
node3.v = "a";
Node node2 = new Node();
node2.v = "b";
node2.next = node3;
Node node1 = new Node();
node1.v = "c";
node1.next = node2;
System.out.println(node1);
}
}
运行截图:

上述代码中,我们使node1的后继为node2,node2的后继为node3,更直观一点

下面,来看一下单链表的具体结构的实现:
public class SinglyLinkedList<E> {
private int size = 0;
private Node<E> first;
private Node<E> last;
public SinglyLinkedList(){
}
private static class Node<E>{
E data;
Node<E> next;
Node(E element,Node<E> next){
this.data = element;
this.next = next;
}
}
public int size(){
return size;
}
public boolean isEmpty(){
return size() == 0;
}
public boolean contains(Object o){
if(o == null){
for(Node<E> x = first;x!=null;x = x.next){
if(x.data == null){
return true;
}
}
}else{
for(Node<E> x = first;x!=null;x = x.next){
if(o.equals(x.data)){
return true;
}
}
}
return false;
}
public boolean add(E e){
final Node<E> newNode = new Node<>(e,null);
final Node<E> l = last;
last = newNode;
if(l == null){
first = newNode;
last = newNode;
}else{
l.next = newNode;
}
size++;
return true;
}
public E get(int index){
if(index < 0 || index > size - 1){
throw new IndexOutOfBoundsException("index " + index + "out of bounds");
}
Node<E> x = first;
for(int i = 0;i < index;i++){
x = x.next;
}
return x.data;
}
public E set(int index,E element){
if(index < 0 || index > size - 1){
throw new IndexOutOfBoundsException("index " + index + "out of bounds");
}
Node<E> x = first;
for(int i = 0; i< index; i++){
x = x.next;
}
E oldValue = x.data;
x.data = element;
return oldValue;
}
public E remove(int index){
if(index < 0 || index > size - 1){
throw new IndexOutOfBoundsException("index " + index + "out of bounds");
}
Node<E> x,p;
if(index == 0){
x = first;
first = first.next;
}else{
p = first;
for(int i = 0;i < index-1;i++){
p = p.next;
}
x = p.next;
p.next = x.next;
}
final E element = x.data;
x.data = null;
size--;
return element;
}
public void addFirst(E e){
final Node<E> f = first;
final Node<E> newNode = new Node<>(e,null);
first = newNode;
if(f == null){
last = newNode;
}else{
newNode.next = f;
}
size++;
}
public void addLast(E e){
add(e);
}
}
public void addLast(E e){
add(e);
}
public E removeFirst(){
return remove(0);
}
public E removeLast(){
return remove(size-1);
}
方法说明:我们首先定义了链表的头节点和尾节点,为了方便我们后续的操作(比如判断链表是否为空等),然后定义链表的元素个数,这俩参考集合中.size()方法,
然后声明一个无参构造器,用来实例化;接着,定义链表的结构,很显然,这是一个内部类;因为Java中没有指针的概念,在这里Node<E> next表示引用的概念(地址);
一个单链表包含两部分,一部分数据域一部分指针域(个人叫法:引用域);
第一个方法,用来返回单链表中的元素个数;第二个方法用来查看链表是否为空;第三个方法查看链表是否包含某元素o;然后依次是增加元素,修改元素,删除元素等;
数据结构之单链表(基于Java实现)的更多相关文章
- 数据结构之单链表的实现-java
一.单链表基本概念 单链表是一种链式存取的数据结构,用一组地址任意的存储单元(一般是非连续存储单元)存放线性表中的数据元素.链表中的数据是以结点来表示的,每个结点的构成:元素data + 指针next ...
- 线性表概述及单链表的Java实现
一.线性表概述 线性表是指一组数据元素之间具有线性关系的元素序列,它表现为:除第一个元素没有直接前驱元素.最后一个元素没有直接后继元素外,其余所有元素都有且仅有一个直接前驱元素和直接后继元素. 根据存 ...
- Python数据结构之单链表
Python数据结构之单链表 单链表有后继结点,无前继结点. 以下实现: 创建单链表 打印单链表 获取单链表的长度 判断单链表是否为空 在单链表后插入数据 获取单链表指定位置的数据 获取单链表指定元素 ...
- javascript数据结构之单链表
下面是用javascript实现的单链表,但是在输出的时候insert方法中存在问题,chrome的console报错说不能读取空的属性,调试了很久都没有通过,先在这里存着,以后再来修改一下. //数 ...
- 数据结构(一) 单链表的实现-JAVA
数据结构还是很重要的,就算不是那种很牛逼的,但起码得知道基础的东西,这一系列就算是复习一下以前学过的数据结构和填补自己在这一块的知识的空缺.加油.珍惜校园中自由学习的时光.按照链表.栈.队列.排序.数 ...
- 数据结构(2):单链表学习使用java实现
单链表是单向链表,它指向一个位置: 单链表常用使用场景:根据序号排序,然后存储起来. 代码Demo: package com.Exercise.DataStructure_Algorithm.Sing ...
- Java数据结构之单链表
这篇文章主要讲解了通过java实现单链表的操作,一般我们开始学习链表的时候,都是使用C语言,C语言中我们可以通过结构体来定义节点,但是在Java中,我们没有结构体,我们使用的是通过类来定义我们所需要的 ...
- Java数据结构-03单链表(二)
在之前我们封装了一些操作在接口类中,并在抽象类实现了相同的方法.下面我们开始写代码: 无头结点单链表:(注意下面的AbstractList是之前抽取的类,不是java.util包下的类) public ...
- 图解Java数据结构之单链表
本篇文章介绍数据结构中的单链表. 链表(Linked List)介绍 链表可分为三类: 单链表 双向链表 循环列表 下面具体分析三个链表的应用. 单链表 链表是有序的列表,它在内存中存储方式如下: 虽 ...
随机推荐
- 在Mac Os(苹果)上用手机抓包软件Charles抓取微信小程序中的高清无水印视频
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_118 手机抓包是一名测试工程师常备的技能,比如我想查看一个接口请求的参数.返回值,还有移动设备上的http请求.https请求,这 ...
- npm run dev 启动项目报错我的解决办法
我的报错截屏 解决方案 1. config文件中 index 文件中的 host 值如果是数字串就将其改为 localhost 2. 再次尝试 如果有遇到其他问题阔以将 node-mo ...
- 开源图编辑库 NebulaGraph VEditor 的设计思路分享
本文首发于 NebulaGraph 公众号 NebulaGraph VEditor 是一个拥有高性能.高可定制的所见即所得图可视化编辑器前端库. NebulaGraph VEditor 底层基于 SV ...
- Git 使用技巧(一):合并分支
在合并分支之前最好保证你所有的分支都是最新的,所以你可以使用 git pull origin branchName 来拉取远程仓库到本地仓库. 假如有一个 dev 分支需要合并到 master 分支中 ...
- HandInDevil 的头发 (分 块)
题面 H a n d I n D e v i l \rm HandInDevil HandInDevil 的头发很油,因此随时有跳蚤跳上 H a n d I n D e v i l \rm HandI ...
- CF1204E Natasha, Sasha and the Prefix Sums (卡塔兰数推理)
题面 题解 把题意变换一下,从(0,0)走到(n,m),每次只能网右或往上走,所以假设最大前缀和为f(n),那么走的时候就要到达但不超过 y = x-f(n) 这条线, 我们可以枚举答案,然后乘上方案 ...
- 【java】学习路径45-多线程-线程生命周期
线程分为五大状态:新建.就绪.运行.阻塞.死亡. New,Runnable,Running,Blocked,Terminated. 新建状态(New: 创建好一个系统对象,在调用start()之前,线 ...
- Centos7中用Docker安装MySQL教程
第一步 安装Docker 1.1 参考这位博主给出的命令安装好 https://blog.csdn.net/weixin_43423864/article/details/109481260 第二步 ...
- openstack中Neutron组件简解
一.Neutron概述 Neutron 的设计目标是实现"网络即服务(Networking as a Service)".为了达到这一目标,在设计上遵循了基于 SDN 实现网络虚拟 ...
- SpringMvc(四)- 下载,上传,拦截器
1.图片下载 图片下载:将服务器端的文件以流的形式写到客户端,通过浏览器保存到本地,实现下载: 1.1 图片下载步骤 1.通过session获取上下文对象(session.getServletCont ...