链表
public class MyLinked<T> {
//链表内元素个数
private int size = 0;
//链表的头元素
private Node<T> first;
private Node<T> last;
public MyLinked(){
}
public void display(){
Node<T> node = first;
for (int i = 0; i < size; i++) {
System.out.println(node.item);
node = node.next;
}
}
//增
//默认末尾增加
public void add(T data){
//首先创建这么一个节点
Node<T> node = new Node<>(data,null);
if (size == 0){
//当前是一个空链表
first = node;
last = node;
size++;
return;
}
//不是空链表
//让之前的尾节点指向它
last.next = node;
//让新节点称为新的尾部节点
last = node;
size++;
}
//指定位置增加
public void add(int index, T data){
if (size == 0){
//当前是一个空链表
Node<T> node = new Node<>(data,null);
first = node;
last = node;
size++;
return;
}
//首先找到指定位置的那个节点
Node<T> oldNode = node(index);
//找到前一个节点
Node<T> preNode = preNode(index);
//创建插入节点
Node<T> newNode = new Node<>(data,oldNode);
//对前一个节点进行判断
if (preNode == null){
//代表被插入的位置是头
first = newNode;
}else {
preNode.next = newNode;
}
//对下一个节点进行空判断
if (oldNode.next == null) {
//说明被插入的那个位置原本是尾部
//让新节点称为尾部节点
last = newNode;
}
size++;
}
//删
public void remove(int index){
//找到被删除的节点
Node<T> node = node(index);
//除此之外还要找到上一个节点
Node<T> preNode = preNode(index);
//对前驱进行判断
if (preNode == null){
//被删除的是头部
first = node.next;
}else {
//让前驱指向后继
preNode.next = node.next;
}
//如果删除的是尾节点
if (node.next == null) {
//如果被删除的节点是尾节点
last = preNode;
}
size--;
}
//改
public void set(int index, T data){
Node<T> node = node(index);
node.item = data;
}
//查
public T get(int index){
//首先进行越界判断
checkBoundary(index);
//根据索引查找到内容
Node<T> node = first;
for (int i = 0; i < index; i++) {
node = node.next;
}
//
return node.item;
}
//根据索引查找索引
private Node<T> node(int index){
checkBoundary(index);
//因为是单向的所以只能从头开始查找
Node<T> node = first;
for (int i = 0; i < index; i++) {
node = node.next;
}
return node;
}
private Node<T> preNode(int index){
Node<T> node = null;
if (index - 1 >= 0){
node = node(index - 1);
}
return node;
}
private void checkBoundary(int index){
if((index + 1) > size||index < 0){
throw new IndexOutOfBoundsException("超出链表长度");
}
}
//节点内部类
private static class Node<T>{
//节点保存的元素
T item;
//节点指向的下一个节点
Node<T> next;
public Node(T item, Node<T> next) {
this.item = item;
this.next = next;
}
@Override
public String toString() {
return "Node{" +
"item=" + item +
", next=" + next +
'}';
}
}
}
测试类
package edu.pdsu.collection;
import org.junit.Test;
public class MyLinkedMethodTest {
@Test
public void testDefaultAdd(){
MyLinked<String> list = new MyLinked<>();
//默认添加
list.add("1");
list.add("2");
list.add("3");
list.display();
//1
//2
//3
}
@Test
public void testIndexAdd(){
MyLinked<String> list = new MyLinked<>();
//默认添加
list.add("1");
list.add("2");
list.add("3");
list.add(2,"哇真的是你啊");
list.display();
//1
//2
//哇真的是你啊
//3
}
@Test
public void testIndexAddAtZero(){
MyLinked<String> list = new MyLinked<>();
list.add(0,"123");
list.display();
}
@Test
public void testGet(){
MyLinked<String> list = new MyLinked<>();
//默认添加
list.add("1");
list.add("2");
list.add("3");
String s = list.get(0);
System.out.println(s);//1
}
@Test
public void testRemove(){
MyLinked<String> list = new MyLinked<>();
//默认添加
list.add("1");
list.add("2");
list.add("3");
list.remove(0);
list.display();
//2
//3
}
@Test
public void testSet(){
MyLinked<String> list = new MyLinked<>();
//默认添加
list.add("1");
list.add("2");
list.add("3");
list.set(0,"哇真的是啊");
list.display();
//哇真的是啊
//2
//3
}
@Test
public void testException(){
MyLinked<String> list = new MyLinked<>();
//默认添加
list.add("1");
try{
list.add(3,"你好");
}catch (Exception e){
e.printStackTrace();
}
try{
list.remove(4);
}catch (Exception e){
e.printStackTrace();
}
try{
list.set(5,"哇");
}catch (Exception e){
e.printStackTrace();
}
//java.lang.IndexOutOfBoundsException: 超出链表长度
}
}