简单实现单向链表。
Java中有自己的链表数据结构LinkedList,今天我们手动实现一个单向链表,以加深对Java底层数据结构的理解,感兴趣的老铁可以对比Java底层代码,提出宝贵意见。
import java.lang.module.FindException;
import java.util.Objects;
/**
* 简单实现链表
*/
public class MyLink {
private int size;
Node head;
/**
* 在链表尾部插入一个元素
* @param data 要插入的数据
*/
public void add(Object data){
Node newNode = new Node(data);
if(head==null){
head = newNode;
}else{
Node tempNode=head;
while(tempNode.next!=null){
tempNode = tempNode.next;
}
tempNode.next = newNode;
}
size++;
}
/**
* 在链表头部插入一个元素
* @param data 要插入的数据
*/
public void addHead(Object data){
Node newNode = new Node(data);
if(head==null){
head = newNode;
}else{
newNode.next=head;
head=newNode;
}
size++;
}
/**
* 在链表指定位置插入一个元素(有两种场景,一种是指定index,一种是指定data,可以做一个重载)
* @param index 指定下标
* @param data 要插入的数据
*/
public void insert(int index,Object data){
Node newNode = new Node(data);
if(index>=size||index<0){
throw new IndexOutOfBoundsException("给定的下标超出链表长度或格式不正确");
}else{
if(index==0){//在下标为零的位置插入,就是从头部插入
addHead(data);
}else{
Node target=head;
for(int i = 0;i<index-1;i++){
target = target.next;
}
newNode.next = target.next;
target.next = newNode;
size++;
}
}
}
/**
* 在目标数据前面插入一个元素
* @param target 目标数据
* @param data 要插入的数据
*/
public void insert(Object target,Object data){
Node newNode = new Node(data);
if(Objects.equals(target,head.data)){
addHead(data);
return;
}else{
for(Node temp = head;temp.next!=null;temp = temp.next){
if(Objects.equals(target,temp.next.data)){//这里的next可以控制元素插入到目标元素之前还是之后
newNode.next = temp.next;
temp.next = newNode;
size++;
return;
}
}
}
//throw new FindException("指定的目标数据不存在");
System.out.println("指定的目标数据不存在");
}
/**
* 从链表尾部删除一个元素
*/
public void deleteTail(){
for(Node temp = head;temp.next!=null;temp=temp.next){
if(temp.next.next==null){
temp.next=null;
size--;
return;
}
}
}
/**
* 从链表头部删除一个元素
*/
public void deleteHead(){
head = head.next;
size--;
}
/**
* 从链表指定位置删除一个元素(两种场景,一种是删除指定下标位置的元素,一种是删除值为目标值的元素(只删第一次出现的位置))
* @param index 指定下标
*/
public void delete(int index){
if(index >= size||index <0 ){
throw new IndexOutOfBoundsException("给定的下标超出链表长度或格式不正确");
}else{
if(index==0){
deleteHead();
}else{
int i=0;
for(Node temp = head;temp.next!=null;temp = temp.next){
if(i==index-1){
temp.next=temp.next.next;
size--;
return;
}
i++;
}
}
}
}
/**
* 删除值为data的元素(一次)
* @param data
*/
public void delete (Object data){
for(Node temp = head;temp.next!=null;temp = temp.next){
if(Objects.equals(data,head.data)){
deleteHead();
return;
}else {
if (Objects.equals(data, temp.next.data)) {
temp.next = temp.next.next;
size--;
return;
}
}
}
System.out.println("指定的目标数据不存在");
}
/**
* 修改链表中指定位置元素的值
* @param index 指定下标
* @param data 修改后的值
*/
public void update(int index,Object data){
if(index>=size||index<0){
throw new IndexOutOfBoundsException("指定下标超出列表长度或下标格式不正确");
}else if(index == 0){
head.data = data;
}else{
Node temp = head;
for(int i = 0;i<size;i++){
if(i==index-1){
temp.next.data = data;
}
temp = temp.next;
}
}
}
/**
* 获取链表指定位置元素的值
*
* @param index 指定下标
*/
public Object get(int index){
if(index>=size||index<0){
throw new IndexOutOfBoundsException("指定下标超出列表长度或下标格式不正确");
}else if(index == 0){
return head.data;
}else{
Node temp = head;
for(int i = 0;i<size;i++){
if(i==index-1){
return temp.next.data;
}
temp = temp.next;
}
}
return null;
}
//遍历链表
public void print(){
Node tempNode=head;
while(tempNode!=null){
System.out.println(tempNode.data);
tempNode = tempNode.next;
}
}
//获取链表元素个数
public int size(){
return size;
}
class Node{
Object data;
Node next;
Node(Object data){
this.data = data;
this.next = null;
}
}
}