数据结构之单链表(基于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)介绍 链表可分为三类: 单链表 双向链表 循环列表 下面具体分析三个链表的应用. 单链表 链表是有序的列表,它在内存中存储方式如下: 虽 ...
随机推荐
- 使用OnPush和immutable.js来提升angular的性能
angular里面变化检测是非常频繁的发生的,如果你像下面这样写代码 <div> {{hello()}} </div> 则每次变化检测都会执行hello函数,如果hello函数 ...
- Java开发学习(十七)----AOP案例之测量业务层接口执行效率
一.需求分析 这个需求比较简单 需求:任意业务层接口执行均可显示其执行效率(执行时长) 这个的目的是查看每个业务层执行的时间,这样就可以监控出哪个业务比较耗时,将其查找出来方便优化. 具体实现的思路: ...
- YII事件EVENT示例
模型中/** * 在初始化时进行事件绑定 */ public function init() { $this->on(self::EVENT_HELLO,[$this,'sendMail']); ...
- Vue 基本列表 && 数据过滤与排序
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8" /> 5 & ...
- Sampler类定义
此是所有采样的基类,这样定义的好处是,我们可以分别测试每一个采样算法. 类定义: #pragma once #ifndef __SAMPLER_HEADER__ #define __SAMPLER_H ...
- 杭州思科对 Apache DolphinScheduler Alert 模块的改造
杭州思科已经将 Apache DolphinScheduler 引入公司自建的大数据平台.目前,杭州思科大数据工程师 李庆旺 负责 Alert 模块的改造已基本完成,以更完善的 Alert 模块适应实 ...
- BZOJ3037 创世纪(基环树DP)
基环树DP,攻的当受的儿子,f表选,g表不选.并查集维护攻受关系.若有环则记录,DP受的后把它当祖宗,再DP攻的. #include <cstdio> #include <iostr ...
- [BJDCTF2020]Mark loves cat-1|源代码泄露|变量覆盖
主要考察了:源代码泄露.变量覆盖 共展示了三种获取flag的方式 1.打开题目查看未发现有效信息,查看源代码信息,发现返回的dog信息,结果如下: 2.使用dirmap进行目录扫描,发现了.git/c ...
- java-RandomAccessFile操作以及IO流简单使用
1.1RandomAccessFile--使用RAF读写基本类型数据,以及了解Raf的指针操作 write有相对应的写入基本类型的方法 void seek(Long pos)调整RAF指针位置,可以在 ...
- CSS 笔记目录
布局 CSS 布局(一):Flex 布局 选择器 CSS 选择器(一):属性选择器 CSS 选择器(二):子代选择器(>)