关于单链表的增删改查方法的递归实现(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 ...
随机推荐
- 关于CTO角色的认知
从3月份到现在2个月过去了,整个数据平台从0到1,算是有了一个基本的样子,跌跌撞撞的勉强支撑起运营的一些基本业务,当然这仅仅是开始,下一步还要从零打造自己的UBS系统,想想都兴奋呢!接下来总结下自己这 ...
- 安卓开发笔记(二十八):仿写IOS switch选择器控件实现,checkbox
我们先来看看效果: 这里我们主要使用了github上的一个开源项目,配置起来比较方便,下面解释一下该如何使用:首先是:Gradle文件当中进行配置: dependencies { implementa ...
- 文本离散表示(一):词袋模型(bag of words)
一.文本表示 文本表示的意思是把字词处理成向量或矩阵,以便计算机能进行处理.文本表示是自然语言处理的开始环节. 文本表示按照细粒度划分,一般可分为字级别.词语级别和句子级别的文本表示.字级别(char ...
- Java语言编程 - Java第一个程序HelloWorld
3.1 新建Java文件 首先新建一个文件夹,用于存放写的Java程序,例如我存放Java程序的位置为” D:\Files\code\java”. 在该文件夹中,右键新建一个文本文档 将文件名重命名为 ...
- Spring Boot 2.0 WebFlux 教程 (一) | 入门篇
目录 一.什么是 Spring WebFlux 二.WebFlux 的优势&提升性能? 三.WebFlux 应用场景 四.选 WebFlux 还是 Spring MVC? 五.异同点 六.简单 ...
- Visio打开或取消箭头的自动吸附和自动连接
在用Visio画图时Visio的自动对齐.自动连接.自动吸附功能确实能带了很多便利.但在画连接线时,Visio总是自动连接箭头与图形的固定节点,想要微调一下连接位置,就显得很不方便,需要关闭自动连接功 ...
- 【RecyclerView优化】
1.局部刷新 (1)避免整个列表的数据更新,只更新受影响的布局.例如,加载更多时,不使用notifyDataSetChanged(),而是使用notifyItemRangeInserted(range ...
- RabbitMQ 消息队列 入门 第一章
RabbitMQ : 官网:https://www.rabbitmq.com/ GitHub:https://github.com/rabbitmq?q=rabbitmq 第一步安装: 点击 htt ...
- .net Lambda表达式与Linq (LINQ TO object)
Lambda表达式,是用来写匿名方法的. 在委托用得比较多,因为委托是传递方法的. 定义几个委托: public delegate void DoNoThing();//无参无返回值 publ ...
- 学习python的第二天
4.26自我总结 一.程序语言 1.机械语言 由于0和1组成 优点:执行效率快 缺点:操作麻烦繁琐 2.汇编语言 比机械语言好点 优点:比机械语言操作方便 缺点,执行慢 3.高级语言 主要两个,jav ...