Java描述数据结构之链表的增删改查
链表是一种常见的基础数据结构,它是一种线性表,但在内存中它并不是顺序存储的,它是以链式进行存储的,每一个节点里存放的是下一个节点的“指针”。在Java中的数据分为引用数据类型和基础数据类型,在Java中不存在指针的概念,但是对于链表而言的指针,指的就是引用数据类型的地址。
链表和数组都是线性的数据结构,对于数组而言其长度是固定的,由于在内存中其是连续的,因此更适合做查找与遍历,而链表在内存中是并不是顺序存储的,但是由于其是通过“指针”构成的,因此在插入、删除时比较数组更为的方便。
下面的代码通过内部类并结合递归的方式来实现了一个简单的用Java语言描述的链表的数据结构。
首先来看一下,链表数据结构的定义,代码如下:
class NodeManager {
private Node root; // 根节点
private int currentIndex = 0; // 节点的序号,每次操作从0开始
public void add(int data) {}
public void delNode(int data) {}
public void print() {}
public boolean findNode(int data) {}
public boolean updateNode(int oldData, int newData) {}
// 向索引之前插入
public void insert(int index, int data) {}
// 谁拥有数据,谁提供方法
class Node {
private int data;
private Node next; // 把当前类型作为属性
public Node(int data) {
this.data = data;
}
public void setData(int data) {
this.data = data;
}
public int getData() {
return data;
}
// 添加节点
public void addNode(int data) {}
// 删除节点
public void delNode(int data) {}
// 输出所有节点
public void printNode() {}
// 查找节点是否存在
public boolean findNode(int data) {}
// 修改节点
public boolean updateNode(int oldData, int newData) {}
// 插入节点
public void insertNode(int index, int data) {}
}
}
对于链表的定义来说,NodeManager类是用来管理链表操作的,而成员内部类Node是用于提供链表数据与链式结构的。对于类的使用者来说,并不直接访问数据,因此操作的是NodeManager类,而内部类Node提供了真正的数据管理,因此Node类需要提供真正的数据操作方法,对于NodeManager类中也需要提供一套由外部来操作链表的方法。因此,在NodeManager类和Node类中都提供了看似相同的方法,但实际的意义并不相同。
下面来查看NodeManager类和Node类中的add()方法,代码如下:
public void add(int data) {
if ( root == null ) {
root = new Node(data);
} else {
root.addNode(data);
}
}
// 添加节点
public void addNode(int data) {
if ( this.next == null ) {
this.next = new Node(data);
} else {
this.next.addNode(data);
}
}
代码中上面的方法是NodeManager类中的方法,而下面的方法是Node类中的方法。
在Manager类中提供了一个root的成员变量,它用于管理链表的头节点,因此在添加节点时,会先判断root是否为空,如果为空则直接将节点由root来进行保存,如果root不为空,则通过Node类中的addNode()方法来进行添加,添加到思路是找到当前链表的最后一个节点,并将新添加到节点赋值给最后一个节点的next成员变量中。
对于链表的其他操作也是相同的思路,关于链表增删改查和输出的完整代码如下:
class NodeManager {
private Node root; // 根节点
private int currentIndex = 0; // 节点的序号,每次操作从0开始
public void add(int data) {
if ( root == null ) {
root = new Node(data);
} else {
root.addNode(data);
}
}
public void delNode(int data) {
if ( root == null ) return ;
if ( root.getData() == data ) {
Node tmp = root;
root = root.next;
tmp = null;
} else {
root.delNode(data);
}
}
public void print() {
if ( root != null ) {
System.out.print(root.getData() + " ");
root.printNode();
System.out.println();
}
}
public boolean findNode(int data) {
if ( root == null ) return false;
if ( root.getData() == data ) {
return true;
} else {
return root.findNode(data);
}
}
public boolean updateNode(int oldData, int newData) {
if ( root == null ) return false;
if ( root.getData() == oldData ) {
root.setData(newData);
return true;
} else {
return root.updateNode(oldData, newData);
}
}
// 向索引之前插入
public void insert(int index, int data) {
if ( index < 0 ) return ;
currentIndex = 0;
if ( index == currentIndex ) {
Node newNode = new Node(data);
newNode.next = root;
root = newNode;
} else {
root.insertNode(index, data);
}
}
// 谁拥有数据,谁提供方法
class Node {
private int data;
private Node next; // 把当前类型作为属性
public Node(int data) {
this.data = data;
}
public void setData(int data) {
this.data = data;
}
public int getData() {
return data;
}
// 添加节点
public void addNode(int data) {
if ( this.next == null ) {
this.next = new Node(data);
} else {
this.next.addNode(data);
}
}
// 删除节点
public void delNode(int data) {
if ( this.next != null ) {
if ( this.next.getData() == data ) {
Node tmp = this.next;
this.next = this.next.next;
tmp = null;
} else {
this.next.delNode(data);
}
}
}
// 输出所有节点
public void printNode() {
if ( this.next != null ) {
System.out.print(this.next.getData() + " ");
this.next.printNode();
}
}
// 查找节点是否存在
public boolean findNode(int data) {
if ( this.next != null ) {
if ( this.next.getData() == data ) {
return true;
} else {
return this.next.findNode(data);
}
}
return false;
}
// 修改节点
public boolean updateNode(int oldData, int newData) {
if ( this.next != null ) {
if ( this.next.getData() == oldData ) {
this.next.setData(newData);
return true;
} else {
return this.next.updateNode(oldData, newData);
}
}
return false;
}
// 插入节点
public void insertNode(int index, int data) {
currentIndex ++;
if ( index == currentIndex ) {
Node newNode = new Node(data);
newNode.next = this.next;
this.next = newNode;
} else {
this.next.insertNode(index, data);
}
}
}
}
以上就是链表基本操作的完整代码,下面写一个调用的代码进行测试,代码如下:
public class LinkList {
public static void main(String[] args) {
NodeManager nm = new NodeManager();
System.out.println("链表的添加(添加5、4、3、2、1)");
nm.add(5);
nm.add(4);
nm.add(3);
nm.add(2);
nm.add(1);
nm.print();
System.out.println("链表的删除(删除3)");
nm.delNode(3);
nm.print();
System.out.println("链表的查找(查找1)");
System.out.println(nm.findNode(1));
System.out.println("链表的查找(查找10)");
System.out.println(nm.findNode(10));
System.out.println("链表的更新(把1更新为10)");
nm.updateNode(1, 10);
nm.print();
System.out.println("链表的插入(在第1个位置插入20)");
nm.insert(1, 20);
nm.print();
System.out.println("链表的插入(在第0个位置插入30)");
nm.insert(0, 30);
nm.print();
}
}
将代码编译、运行,结果如下图:

对于Java中的集合类中用到了不少的数据结构的知识,等自己状态好的时候学习学习Java集合类的源码。我会努力做一个初级程序员!
我的微信公众号:“码农UP2U”

Java描述数据结构之链表的增删改查的更多相关文章
- 关于单链表的增删改查方法的递归实现(JAVA语言实现)
因为在学习数据结构,准备把java的集合框架底层源码,好好的过一遍,所以先按照自己的想法把单链表的类给写出来了; 写该类的目的: 1.练习递归 2.为深入理解java集合框架底层源码打好基础 学习的视 ...
- Java通过JDBC进行简单的增删改查(以MySQL为例)
Java通过JDBC进行简单的增删改查(以MySQL为例) 目录: 前言:什么是JDBC 一.准备工作(一):MySQL安装配置和基础学习 二.准备工作(二):下载数据库对应的jar包并导入 三.JD ...
- java jdbc 连接mysql数据库 实现增删改查
好久没有写博文了,写个简单的东西热热身,分享给大家. jdbc相信大家都不陌生,只要是个搞java的,最初接触j2ee的时候都是要学习这么个东西的,谁叫程序得和数据库打交道呢!而jdbc就是和数据库打 ...
- AD 域服务简介(三)- Java 对 AD 域用户的增删改查操作
博客地址:http://www.moonxy.com 关于AD 域服务器搭建及其使用,请参阅:AD 域服务简介(一) - 基于 LDAP 的 AD 域服务器搭建及其使用 Java 获取 AD 域用户, ...
- Java对XML文档的增删改查
JAVA增删改查XML文件 最近总是需要进行xml的相关操作. 不免的要进行xml的读取修改等,于是上网搜索,加上自己的小改动,整合了下xml的常用操作. 读取XML配置文件 首先我们需要通过Do ...
- Java连接Redis之redis的增删改查
一.新建一个maven工程,工程可以以jar的形式或war都行,然后导入正确的依赖 <project xmlns="http://maven.apache.org/POM/4.0.0& ...
- java+jsp+sqlserver实现简单的增删改查操作 连接数据库代码
1,网站系统开发需要掌握的技术 (1)网页设计语言,html语言css语言等 (2)Java语言 (3)数据库 (4)等 2,源程序代码 (1) 连接数据库代码 package com.jaovo.m ...
- Java 使用控制台操作实现数据库的增删改查
使用控制台进行数据库增删改查操作,首先创建一个Java Bean类,实现基础数据的构造,Get,Set方法的实现,减少代码重复性. 基本属性为 学生学号 Id, 学生姓名 Name,学生性别 Sex, ...
- java数据库(MySQL)之增删改查
1.查询数据 先救从简单的来吧,之前我们实现了将数据库表格信息读取到一个List集合中,数据库的查询,实 际上就是对这个集合的查询: public class Show { public static ...
随机推荐
- Developing User Interfaces
Developing a User Interface with ADF Faces Purpose This tutorial covers developing the user interf ...
- “《编程珠玑》(第2版)第2章”:C题(查找变位词,排序)
C题是这样子的: 给定一个英语字典,找出其中的所有变位词集合.例如,“pots”.“stop”和“tops”互为变位词,因为每一个单词都可以通过改变其他单词中字母的顺序来得到. 下段分析摘自该书(P1 ...
- Erlang cowboy 入门参考之现代Web的发展历史
Erlang cowboy 入门参考之现代Web发展史 原文: http://ninenines.eu/docs/en/cowboy/1.0/guide/modern_web/ 让我回顾一下web技术 ...
- 【LaTeX排版】LaTeX论文模版
本文是对前面LaTeX论文排版文章的总结.前面的几篇文章是分别从论文的几个方面来讲述LaTeX的排版问题,这里综合了前面的内容,给出了论文排版的模版. 模版的使用: 1.首先建立一个main.tex文 ...
- HBase开启LZO
hbase只支持对gzip的压缩,对lzo压缩支持不好.在io成为系统瓶颈的情况下,一般开启lzo压缩会提高系统的吞吐量.但这需要参考具体的应用场景,即是否值得进行压缩.压缩率是否足够等等. 想要hb ...
- AndroidStudio加快Gradle速度的方法-android study之旅(103)
方法1 打开setting,搜索compiler ,按照如图配置,不要问我为什么,宝宝心里苦~ 方法2 到开项目的根目录的gradle.properties ,把下面的注释解除 org.gradle. ...
- The 11th tip of DB Query Analyzer
The 11th tip of DB Query Analyzer MA Gen feng ...
- python3+django2 开发易语言网络验证(中)
第四步:网络验证的逻辑开发 1.将model注册到adminx.py中 1.在apps/yanzheng目录下新建admin.py 文件,添加代码: import xadmin from xadmin ...
- j2EE经典面试题
1. hibernate中离线查询去除重复项怎么加条件? dc.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 2. http协议及端口,sm ...
- python---内置模块
时间模块 时间分为三种类型:时间戳,结构化时间,格式化时间 #时间模块,time import time #时间戳 x = time.time() time.gmtime() #将时间戳转换成UTC时 ...