谈起链表,相信很多人都用过。但是他的内部实现是什么样的呢。其实我个人的理解是:自己指向自己,将自己作为自己的成员属性,和套娃的意思大概是一个道理吧
比如我定义了一个类Node,Node中有两个成员变量data和next,其中data是数据元素,next是指向下一个数据的地址,也可以称next是指向Node的一个变量(这里的Node是我们实例出来的一个新的对象)。
package com.example.speinrsecurity.config;
public class NodeLink {
//node节点(链表我个人的理解就是自己指向自己,即将自己作为自己的属性,外面看到的只有一个node,
// 但是node里面还有指向之前node,因此达到的链式的结构)
private Node head;
private Integer size = 0;
public NodeLink() {
}
public NodeLink(Integer data) {
addHeadNode(data);
}
public Integer getSize() {
return size;
}
//内部类。和c语言上的结构体类似
private class Node {
Integer data;
Node next;
public Node() {
}
}
//添加节点,头插法
public void addHeadNode(Integer data) {
if (head == null) {
head = new Node();
head.data = data;
head.next = null;
} else {
Node node = new Node();
node.data = data;
//这个时候node的next得到了head的地址,那么node就得到了head的数据
node.next = head;
// 此时head地址指向了node,那么head的next也就变成了node的next,head的地址和和node的地址相等
// 又因为node的next指向的是之前head,虽然此时的head指向变了,但是node的next指向之前head的地址没变
// (这里只是将指针的指向改变了而又,之前指向的内存地址没有改变,在大的层面上,
// 地址指向变了,但是在小的层面上【比如node里面的next就没有改变】)
head = node;
}
size++;
}
//尾插法
public void addLastValue(Integer data) {
if (head == null) {
head = new Node();
head.data = data;
head.next = null;
}
Node t = head;
while (t.next != null) {
t = t.next;
}
// 此时t的next为空
Node node1 = new Node();
node1.data = data;
node1.next = null;
t.next = node1;//将数据拼接到t的next上
size++;
}
//打印链表
public void printNode() {
Node nodeLink = head;
System.out.print("元素个数:");
while (nodeLink != null) {
System.out.print(nodeLink.data);
if (nodeLink.next != null) {
System.out.print("--->");
}
nodeLink = nodeLink.next;
}
}
public boolean deleteNode(Integer data) {
Node node = head;
if (head == null) {
System.out.println("链表是空的");
return false;
}
if (head.data.equals(data)) {//判断第一个数是否相等或者当链表只有一个数时
head = head.next;
return true;
}
while (node.next != null) {
if (node.next.data.equals(data)) {
node.next = node.next.next;
return true;
}
node = node.next;
}
return false;
}
public void insertValue(Integer data, Integer position) {
if (position.equals(1)) {
addHeadNode(data);
} else {
if (position == size+1) {
addLastValue(data);
return;
}else if (position >size+1 ){
System.out.println("插入的位置超出链表长度,NodeLink.size=" + size);
return;
}
Integer index = 1;
Node temp = head;
Node node = new Node();
node.data = data;
while (temp.next != null) {
//选择equals的原因是Integer的类型有关
if (index.equals(position - 1)) {//position是当前节点,那么我们需要找到前一个节点,才能改变指针
node.next = temp.next;
temp.next = node;
return;
}
index++;
temp = temp.next;
}
temp.next = node;
}
size++;
}
public static void main(String[] args) {
NodeLink nodeLink = new NodeLink();
nodeLink.addHeadNode(1);
nodeLink.addHeadNode(2);
nodeLink.addHeadNode(3);
nodeLink.addHeadNode(4);
nodeLink.addHeadNode(5);
nodeLink.addLastValue(6);
nodeLink.printNode();
System.out.println("n-------------------------------");
// System.out.println("删除:"+nodeLink.deleteNode(1));
System.out.println("n-------------------------------");
nodeLink.printNode();
System.out.println("n插入数据");
nodeLink.insertValue(7, 1);
System.out.println("n-------------------------------");
nodeLink.printNode();
}
}



