关于单链表的增删改查方法的递归实现(JAVA语言实现)
因为在学习数据结构,准备把java的集合框架底层源码,好好的过一遍,所以先按照自己的想法把单链表的类给写出来了;
写该类的目的:
1.练习递归
2.为深入理解java集合框架底层源码打好基础
学习的视频看的慕课网liuyubobo老师的课程:Java玩转数据结构 从入门到进阶
废话不多说,以下为源代码:
public class LinkedList<E extends Comparable<E>> {
//链表节点内部类
private class Node{
E e;
Node next;
public Node(E _e,Node _next){
this.e = _e;
this.next = _next;
}
public Node(E _e){
this(_e, null);
}
public Node(){
this(null, null);
}
}
//头节点
private Node head;
//链表实际存储大小
private int size;
//无参构造函数
public LinekedList(){
this.head = null;
this.size = 0;
}
//判断链表是否为空
public boolean isEmpty(){
return this.size == 0;
}
public int size(){
return this.size;
}
//在链表头添加节点
public void addFirst(E e){
add(0, e);
}
//在链表尾添加节点
public void addLast(E e){
add(size, e);
}
//在链表指定位置添加节点
public void add(int index,E e){
if (index < 0 || index > size) {
throw new IllegalArgumentException("Index is error.");
}
head = add(index, e, head);
}
//通过递归实现链表的添加
private Node add(int index,E e,Node node){
if (index == 0 && node == null) {
this.size++;
return new Node(e);
}
if (index == 0) {
this.size++;
Node newNode = new Node(e);
//newNode.next = node.next;
newNode.next = node;
//node.next = newNode;
return newNode;
}
node.next = add(index - 1, e, node.next);
return node;
}
/**
* 用于根据索引查找对应的节点,
* @param index
* @param node
* @return 相应的节点对象
*/
private Node getElementByIndex(int index,Node node){
if (index == 0 && node != null) {
return node;
}
Node ret = getElementByIndex(index - 1, node.next);
return ret;
}
//删除链表头节点
public E removeFirst(){
return remove(0);
}
//删除链表尾结点
public E removeLast(){
return remove(size - 1);
}
//删除指定位置节点,并返回删除节点值
public E remove(int index){
if (isEmpty()) {
throw new IllegalArgumentException("List is empty.");
}
if (index < 0 || index >= size) {
throw new IllegalArgumentException("Index is error.");
}
Node ret = getElementByIndex(index, head);
head = remove(index, head);
return ret.e;
}
//递归删除节点值
private Node remove(int index,Node node){
if (node == null) {
return node;
}
if (index == 0) {
Node delNode = node;
node = delNode.next;
delNode.next = null;
this.size--;
return node;
}
node.next = remove(index - 1, node.next);
return node;
}
//修改指定位置节点的值,通过递归实现
public void set(int index,E e){
if (isEmpty()) {
throw new IllegalArgumentException("List is empty.");
}
if (index < 0 || index >= size) {
throw new IllegalArgumentException("Index is error.");
}
set(index, e, head);
}
private void set(int index,E e,Node node){
if (node == null) {
return;
}
if (index == 0) {
node.e = e;
}
set(index - 1, e, node.next);
return;
}
//获取链表头节点的值
public E getFirst(){
return get(0);
}
//获取链表尾结点的值
public E getLast(){
return get(size - 1);
}
//获取链表制定位置的值,通过递归实现
public E get(int index){
if (isEmpty()) {
throw new IllegalArgumentException("List is empty.");
}
if (index < 0 || index >= size) {
throw new IllegalArgumentException("Index is error.");
}
return get(index, head).e;
}
private Node get(int index,Node node){
if (node == null) {
return node;
}
if (index == 0) {
return node;
}
Node ret = get(index - 1, node.next);
return ret;
}
//查询链表中的节点是否包含值e
public boolean contains(E e){
return contains(e, head);
}
private boolean contains(E e,Node node){
if (node == null) {
return false;
}
if (node.e == e) {
return true;
}
return contains(e, node.next);
}
//重写Object类的toString方法:也是通过链表天然的递归性,来访问
//链表的每一个节点
@Override
public String toString() {
StringBuilder res = new StringBuilder();
res.append("Font -> ");
linkToString(head, res);
return res.toString();
}
private void linkToString(Node node,StringBuilder res){
if (node == null) {
res.append("NULL");
return;
}
res.append(node.e + " -> ");
linkToString(node.next, res);
return;
} /*public static void main(String[] args) {
LinekedList<Integer> ll = new LinekedList<>();
for (int i = 0; i < 13; i++) {
ll.addLast(i);
System.out.println(ll.toString());
}
System.out.println("------------------");
for (int i = 0; i < 11; i++) {
Integer ii = ll.removeFirst();
System.out.println(ii);
System.out.println(ll.toString());
} }*/
}
有一些方法测了,但是有些方法没测,有需要可以自行参考(不保证准确啊...)
该类主要包含链表的增删改查,里面加了索引主要是为了好理解(注:链表是没有索引的).
因为,才刚开始熟悉递归以及数据结构,所以需要各位大佬的多多指正
有建议的可以在评论中指出.
关于单链表的增删改查方法的递归实现(JAVA语言实现)的更多相关文章
- 史上最全单链表的增删改查反转等操作汇总以及5种排序算法(C语言)
目录 1.准备工作 2.创建链表 3.打印链表 4.在元素后面插入元素 5.在元素前面增加元素 6.删除链表元素,要注意删除链表尾还是链表头 7.根据传入的数值查询链表 8.修改链表元素 9.求链表长 ...
- python全栈开发day61-django简单的出版社网站展示,添加,删除,编辑(单表的增删改查)
day61 django内容回顾: 1. 下载: pip install django==1.11.14 pip install -i 源 django==1.11.14 pycharm 2. 创建项 ...
- hibernate对单表的增删改查
ORM: 对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping) 实现对单表的增删改查 向区域表中增加数据: 第一步: 新建一个Da ...
- Django学习笔记(10)——Book单表的增删改查页面
一,项目题目:Book单表的增删改查页面 该项目主要练习使用Django开发一个Book单表的增删改查页面,通过这个项目巩固自己这段时间学习Django知识. 二,项目需求: 开发一个简单的Book增 ...
- 通用mapper的增删改查方法 留存 备忘
Mybatis通用Mapper介绍与使用 前言 使用Mybatis的开发者,大多数都会遇到一个问题,就是要写大量的SQL在xml文件中,除了特殊的业务逻辑SQL之外,还有大量结构类似的增删改查SQ ...
- java实现单链表的增删改以及排序
使用java代码模拟单链表的增删改以及排序功能 代码如下: package com.seizedays.linked_list; public class SingleLinkedListDemo { ...
- Mybatis(一)实现单表的增删改查
1.1 什么是Mybatis MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并 ...
- Spring Data CrudRepository增删改查方法(八)
CrudRepository 的主要方法 long count(); boolean exists(Integer arg0); <S extends StudentPO> S sav ...
- Django REST framework 五种增删改查方法
Django-DRF-视图的演变 版本一(基于类视图APIView类) views.py: APIView是继承的Django View视图的. 1 from .serializers impor ...
随机推荐
- netty源码学习
概述 Netty is an asynchronous event-driven network application framework for rapid development of main ...
- ASP.NET Core 借助 K8S 玩转容器编排
Production-Grade Container Orchestration - Automated container deployment, scaling, and management. ...
- 神奇的Scala Macro之旅(三)- 实际应用
在上一篇中,我们示范了使用macro来重写 Log 的 debug/info 方法,并大致的介绍了 macro 的基本语法.基本使用方法.以及macro背后的一些概念, 如AST等.那么,本篇中,我们 ...
- Python与家国天下
导读:Python猫是一只喵星来客,它爱地球的一切,特别爱优雅而无所不能的 Python.我是它的人类朋友豌豆花下猫,被授权润色与发表它的文章.如果你是第一次看到这个系列文章,那我强烈建议,请先看看它 ...
- 用Docker解决坑爹的环境搭建系列——postgresql
sudo docker pull postgres mkdir -p /data/docker/pgsql sudo docker run -p 54321:5432 --name pgsql -v ...
- [TCP/IP] TCP的传输连接管理
1.连接建立=>数据传输=>连接释放 2.主动发起连接的是客户端,被动接受连接的是服务器 3.三次握手 客户端 ==> SYN是1同步 ,ACK确认标志是0,seq序号是x ==&g ...
- SpringBoot启动原理分析
用了差不多两年的SpringBoot了,可以说对SpringBoot已经很熟了,但是仔细一想SpringBoot的启动流程,还是让自己有点懵逼,不得不说是自己工作和学习的失误,所以以此文对Spring ...
- 教你如何一键反编译获取任何微信小程序源代码(图形化界面,傻瓜式操作)
一键获取微信小程序源代码 Tips: 一键获取微信小程序源码, 使用了C#加nodejs制作 直接解压在D盘根目录下后就可以使用 将小程序文件放到 wxapkg目录下3 这个目录下有一些demo 可以 ...
- MonacoEditor 主动触发代码提示功能
MonacoEditor是微软提供的代码编辑器 vscode即是使用它作为编辑器. 它的开发语言是ts,可以嵌入到浏览器中. 代码提示或者说代码补全功能是我们经常需要定制的部分. 目前它提供的快捷键是 ...
- Javascript高级编程学习笔记(96)—— WebGL(2) 类型化视图
类型化视图 类型化视图一般也被认为是一种类型化数组. 因为其元素必须是某种特定的数据类型,类型化视图都继承自 Dataview Int8Array: 表示8位二补整数(即二进制补数) Uint8Arr ...