Java手写简单Linkedlist一(包括增加,插入,查找,toString,remove功能)
@Java300 学习总结
一、自定义节点
LinkList底层为双向链表。特点为查询效率低,但增删效率高,线程不安全。
链表数据储存在节点,且每个节点有指向上个和下个节点的指针。
创建ggLinkedList类,可以先创建一个节点对象Entry。
public class Entry {
Entry previous;
Entry next;
Object element;
public Entry(Entry previous, Entry next, Object element) {
super();
this.previous = previous;
this.next = next;
this.element = element;
}
public Entry(Object element) {
super();
this.element = element;
}
}
二、增加add方法
LinkedList通过add方法往里面增加元素。
先建一个类。
public class ggLinkedList {
private Entry first; //链表头指针,指向第一个节点
private Entry last; //链表尾指针,指向最后一个节点
private int size; //长度,增加节点和删除节点时++或--
//往链表尾处添加元素
public void add(Object obj) {
Entry entry = new Entry(obj);
if(first == null) {
first = entry;
last = entry;
}else {
entry.previous = last; //新节点头指针指向上一个节点
entry.next = null; //新节点尾指针指向空
last.next = entry; //上一个节点的尾指针指向新添加节点
last = entry;//尾指针指向新节点
}
size++;//链表长度增加一
}
public static void main(String[] args) {
ggLinkedList list = new ggLinkedList();
list.add('a');
}
}
三、增加toString方法
在ggLinkedList类中,添加toString方法,以数组的形式输出链表每个节点的数据。
在main函数调用System.out.println(list),会默认调用toString方法。
public String toString() {
StringBuilder sb = new StringBuilder("[");
Entry temp = first;
while(temp!=null) {
sb.append(temp.element+",");
temp = temp.next;
}
sb.setCharAt(sb.length()-1,']');
return sb.toString();
}
四、增加get查找方法
get()方法,可以通过传递数字,查找LinkedList对应索引节点上的数据。
public Object get(int index) {
if(index< 0||index > size -1) {
throw new RuntimeException("索引数字不合法" + index);
}
if(index <= (size>>1)) { //索引index小于链表长度的一半,从链表头部开始查找
Entry temp = first;
for(int i = 0;i<index;i++) {
temp = temp.next;
}
return temp.element;
}else
{
Entry temp = last; //索引index大于链表长度的一半,从链表尾部开始查找
for(int i = size-1;i > index;i--) {
temp = temp.previous;
}
return temp.element;
}
}
五、增加remove()删除功能
remove()删除节点,需先定位到目标节点,与get()方法一致,所以可构造getEntry()方法,以简化代码。
public Entry getEntry(int index) {
Entry temp = null;
if(index <= (size>>1)) {
temp = first;
for(int i = 0;i<index;i++) {
temp = temp.next;
}
return temp;
}else
{
temp = last;
for(int i = size-1;i > index;i--) {
temp = temp.previous;
}
return temp;
}
}
重构get()方法
public Object get(int index) {
if(index< 0||index > size -1) {
throw new RuntimeException("索引数字不合法" + index);
}
Entry temp = getEntry(index);
return temp!= null?temp.element:null;
}
remove()方法
public void remove(int index) {
Entry temp = getEntry(index); //索引到指定的节点
Entry up = temp.previous; //上一个节点为up
Entry down = temp.next; // 下一个节点为down
if(temp!= null) {
if(down!= null) { //下一个节点不为空,down的头指针指向上一个节点
down.previous = up;
}
if(up!= null) { //上一个节点不为空,up的的尾指针为下一个节点
up.next = down;
}
if(index == 0) { //移除节点为头节点,链表头指针指向第二个
first = down;
}
if(index == (size-1)) { //移除节点为最后一个,链表尾指针指向倒数第二个
last = up;
}
}
size--;
}
六、增加插入方法
重载add()方法,实现在指定索引位置插入元素。
public void add(int index,Object obj) {
Entry newEntry = new Entry(obj); //新建节点,将它插入在索引节点的前面
Entry down = getEntry(index); //原节点为新插入节点的下一个节点,变量名为down
if(down!=null) { //原节点不为空
Entry up = down.previous; //原节点的上一个节点为上一个节点,变量名为up
if(index == 0) {
down.previous = newEntry; //原节点的前一个为新节点
newEntry.next = down;//新节点的下一个为原节点
first = newEntry;//链表头指针指向新节点
}
else if(index == (size-1)) {
down.next = newEntry; //原节点的下一个为新节点
newEntry.previous = up;//新节点的上一个为up
last = newEntry;//尾指针指向新节点
}else {
down.previous = newEntry;
up.next = newEntry;
newEntry.next = down;
newEntry.previous = up;
}
}
size++;
至此,LinkedList部分方法已实现,后续也可增加其他方法,或泛型。旨在理解底层原理,提升代码能力
Java手写简单Linkedlist一(包括增加,插入,查找,toString,remove功能)的更多相关文章
- Java手写简单HashMap一(包括增加,查找,toString,泛型)
@Java 300 学习总结 HashMap底层采用实现采用了哈希表,结合了"数组和链表". 原理如图 一.定义HashMap类. 首先需要定义一个节点来存储数据,构成链表结构. ...
- 利用Java手写简单的httpserver
前言: 在看完尚学堂JAVA300中讲解如何实现一个最简单的httpserver部分的视频之后, 一.前置知识 1.HTTP协议 当前互联网网页访问主要采用了B/S的模式,既一个浏览器,一个服务器,浏 ...
- 教你如何使用Java手写一个基于链表的队列
在上一篇博客[教你如何使用Java手写一个基于数组的队列]中已经介绍了队列,以及Java语言中对队列的实现,对队列不是很了解的可以我上一篇文章.那么,现在就直接进入主题吧. 这篇博客主要讲解的是如何使 ...
- java 手写 jvm高性能缓存
java 手写 jvm高性能缓存,键值对存储,队列存储,存储超时设置 缓存接口 package com.ws.commons.cache; import java.util.function.Func ...
- java手写多级缓存
多级缓存实现类,时间有限,该类未抽取接口,目前只支持两级缓存:JVM缓存(实现 请查看上一篇:java 手写JVM高性能缓存).redis缓存(在spring 的 redisTemplate 基础实现 ...
- 不使用Tomcat,手写简单的web服务
背景: 公司使用的YDB提供了http的查询数据库服务,直接通过url传入sql语句查询数据-_-||.ydb的使用参照:https://www.cnblogs.com/hd-zg/p/7115112 ...
- 手写简单call,apply,bind
分析一下call的使用方法:call是显示绑定this指向,然后第一个参数是你所指向的this对象,后面跟着多个参数,以逗号隔开 function sum(num1,num2){ return num ...
- 手写Spring MVC框架(二) 实现访问拦截功能
前言 在上一篇文章中,我们手写了一个简单的mvc框架,今天我们要实现的功能点是:在Spring MVC框架基础上实现访问拦截功能. 先梳理一下需要实现的功能点: 搭建好Spring MVC基本框架: ...
- 手写简单的jq雪花飘落
闲来无事,准备写个雪花飘落的效果,没有写太牛逼的特效,极大的简化了代码量,这样容易读取代码,用起来也很简单,对于那些小白简直是福利啊,简单易读易学.先直接上代码吧,然后再一一讲解,直接复制粘贴就可以拿 ...
随机推荐
- Atcoder ABC 139B
Atcoder ABC 139B 题意: 一开始有1个插口,你的插排有 $ a $ 个插口,你需要 $ b $ 个插口,问你最少需要多少个插排. 解法: 暴力模拟. CODE: #include< ...
- Java微信公众号开发梳理
Java微信公众号开发梳理 现在微信公众平台的开发已经越来越普遍,这次开发需要用到微信公众平台.因此做一个简单的记录,也算是给那些没踩过坑的童鞋一些启示吧.我将分几块来简单的描述一下,之后会做详细的说 ...
- MyBatis错误:The server time zone value '?泄???????' is unrecognized or represents more t
原文地址:http://blog.csdn.net/oppo5630/article/details/52162783 解决java.sql.SQLException: The server time ...
- Mybatis generator配置
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration ...
- MyBatis——特殊传参问题小结
近期在写系统报表API的时候遇到MyBatis中的一些特殊写法: 1. 传入两个参数(一般情况下我们更多的是传入一个对象或者map) public List<MarketVehicleModel ...
- python笔记3 闭包 装饰器 迭代器 生成器 内置函数 初识递归 列表推导式 字典推导式
闭包 1, 闭包是嵌套在函数中的 2, 闭包是内层函数对外层函数的变量(非全局变量)的引用(改变) 3,闭包需要将其作为一个对象返回,而且必须逐层返回,直至最外层函数的返回值 闭包例子: def a1 ...
- shell脚本中用到的计算
在shell脚本中计算一般会涉及到let.$(()).$[].bc(另扩展expr).其中let.$(()).$[]都是用来做基本整数运算,bc可以用来做浮点运算. (1).let.$(()).$[] ...
- [转]Android 应用自动更新及6.0,7.0,8.0适配安装
原贴:https://www.jianshu.com/p/ea42040c7ace 原贴:https://www.jianshu.com/p/ea42040c7ace 原贴:https://www.j ...
- 读写Session
读写Session Session是保存在服务端的字典 Session与Cookie有些类似,都是通过字典管理key-value对,只不过Cookie是保存在客户端的字典,而Session是保存在服务 ...
- 生产者-消费者问题与quene模块
生产者-消费者问题与quene模块 下面使用线程锁以及队列来模拟一个典型的案例:生产者-消费者模型.在这个场景下,商品或服务的生产者生产商品,然后将其放到类似队列的数据结构中,生产商品的时间是不确定的 ...