Java实现单链表
前言
模仿jdk的LinkedList写的单链表
一、单链表是什么?
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据
二、实现代码
package com.cxf.study.singlelinked;
/**
* @Description: java实现单链表
* @Author: xiaowang
* */
public class MySingleLinkedList<E> {
// 链表大小
private int size;
// 伪头指针(不存实际数据)
private Node<E> head;
// 尾指针
private Node<E> rear;
/**
* 构造器
*/
public MySingleLinkedList() {
this.size = 0;
Node<E> node = new Node<>(null, null);
this.rear = node;
this.head = node;
}
/**
* 尾插法添加节点
*/
public void add(E e) {
// 拿到旧的尾节点
Node<E> oldRear = rear;
// 新节点
Node<E> newNode = new Node<>(e, null);
// 接链
oldRear.next = newNode;
// 尾指针重新指向尾节点
rear = newNode;
// 计数器
size++;
}
/**下标获取*/
public E get(int index){
this.checkIsIndex(index);
return getNodeByIndex(index).value;
}
/**
* 根据下标删除节点
*/
public E remove(int index) {
// 检查下标
this.checkIsIndex(index);
// 获取该下标的上一个节点
Node<E> lastNode = this.getNodeByIndex(index - 1);
// 获取该下标节点
Node<E> theNode = this.getNodeByIndex(index);
// 接链
lastNode.next = theNode.next;
// 如果删除的是最后一个节点,改变尾指针
if (index == size-1){
lastNode.next = null;
rear = lastNode;
}
// 计数器
size--;
return theNode.value;
}
/**清空链表*/
public void clear(){
for (Node<E> tempNode = head;tempNode!=null;){
Node<E> nextNode = tempNode.next;
tempNode.next = null;
tempNode.value = null;
tempNode = nextNode;
}
rear = head;
size = 0;
}
/**toString*/
public String toString(){
if (size ==0){
return "[]";
}
StringBuilder listStr = new StringBuilder();
listStr.append("[");
for (Node<E> tempNode = head.next;tempNode!=null;){
Node<E> nextNode = tempNode.next;
listStr.append(tempNode.value);
if (nextNode!=null){
listStr.append(",");
}else{
listStr.append("]");
}
tempNode = nextNode;
}
return listStr.toString();
}
/**链表大小*/
public int size(){
return size;
}
/**
* 根据下标添加节点
*/
public void add(int index, E data) {
// 检查是否可以成为新的下标
this.checkBefourIndex(index);
// 获取该下标前一个节点
Node<E> lastNode = this.getNodeByIndex(index - 1);
// 接链
lastNode.next = new Node<>(data, lastNode.next);
// 如果插入的是最后一个,改变尾指针
if (index == size){
rear = lastNode.next;
}
// 计数器
size++;
}
/**
* 根据下标获取节点
*/
private Node<E> getNodeByIndex(int index) {
if (index == -1) {
return head;
}
Node<E> tempNode = head;
for (int i = 0; i <= index; i++) {
tempNode = tempNode.next;
}
return tempNode;
}
/**
* 检查链表中是否已经存在该下标
*/
private void checkIsIndex(int index) {
if (index >= size || index < 0) {
throw new RuntimeException("下标越界,index:" + index + ",size:" + size);
}
}
/**
* 检查链表中是否已经可以添加该下标的节点
*/
private void checkBefourIndex(int index) {
if (index > size || index < 0) {
throw new RuntimeException("下标越界,index:" + index + ",size:" + size);
}
}
/**
* 单链表的节点
*/
private static class Node<E> {
E value;
Node<E> next;
Node(E e, Node<E> next) {
this.value = e;
this.next = next;
}
}
}
三、测试代码
package com.cxf.study.singlelinked;
import java.util.Scanner;
public class TestSingleLinkedList {
public static void main(String[] args) {
MySingleLinkedList<String> list = new MySingleLinkedList<>();
Scanner scanner = new Scanner(System.in);
Scanner scanner2 = new Scanner(System.in);
Scanner scanner3 = new Scanner(System.in);
boolean isCan = true;
while (isCan){
showWord();
int flag = scanner.nextInt();
switch (flag){
case 1 :
System.out.println("请输入要添加的数据:");
String data = scanner2.nextLine();
list.add(data);
System.out.println("添加成功~~~");
break;
case 2 :
System.out.println("请输入下标:");
int index = scanner2.nextInt();
String value = list.get(index);
System.out.println("数据:"+value);
break;
case 3 :
System.out.println("链表数据:\n"+list.toString());
break;
case 4 :
System.out.println("请输入要添加的位置:");
int index2 = scanner3.nextInt();
System.out.println("请输入要添加的数据:");
String dataByIndex = scanner2.nextLine();
list.add(index2,dataByIndex);
System.out.println("添加成功~~~");
break;
case 5 :
System.out.println("链表的元素个数为:"+list.size());
break;
case 6 :
list.clear();
System.out.println("链表已经清空...");
break;
case 7 :
System.out.println("请输入要删除的位置:");
int index3 = scanner3.nextInt();
String oldData = list.remove(index3);
System.out.println("数据:"+oldData+" 已删除...");
break;
default:
isCan = false;
System.out.println("已退出...");
break;
}
}
}
private static void showWord(){
System.out.println("欢迎来到记录系统,"+
"退出:0;"+
"普通添加:1;"+
"下标获取:2;"+
"展示链表:3;"+
"下标添加:4;"+
"查看个数:5;"+
"清空链表:6;"+
"删除元素:7;");
}
}
总结
以上就是今天要讲的内容,本文仅仅简单介绍了单链表的实现以及测试。其他同学肯定有更好的实现,有写的不妥的地方还请指出。上面代码没有进行特别详细的测试,如果有发现bug的童鞋希望能及时提出来,共同学习,一起进步。