链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的 。 相比于顺序表,单链表有其独特的优点:任意位置插入删除时间复杂度为O(1) ,并且没有增容问题,插入一个开辟一个空间。但也有缺点,即以节点为单位存储,不支持随机访问。
class Node {
public int data;
public Node next;
public Node(int data) {
this.data = data;
this.next = null;
}
}
public class MyLinkedList {
public Node head;//保存头节点
//头插法
public void addFirst(int data) {
Node node = new Node(data);
if(this.head == null) {
this.head = node;
return;
}
node.next = this.head;
this.head = node;
}
//打印单链表
public void display() {
Node cur = this.head;
while(cur != null) {
System.out.print(cur.data);
cur = cur.next;
}
System.out.println();
}
//尾插法
public void addLast(int data) {
Node node = new Node(data);
if(this.head == null) {
this.head = node;
return;
}
Node cur = this.head;
while(cur.next != null) {
cur = cur.next;
}
cur.next = node;
}
//查找是否包含关键字key在单链表中
public boolean contains(int key) {
Node node = new Node(key);
Node cur = this.head;
while(cur != null) {
if(cur.data == key ) {
return true;
}
cur = cur.next;
}
return false;
}
//得到单链表的长度
public int size(){
Node cur = this.head;
int count = 0;
while(cur != null) {
count++;
cur = cur.next;
}
return count;
}
//任意位置插入,第一个数据节点为0号下标
public void addIndex(int index,int data) {
if(index == 0) {
addFirst(data);
return;
}
if(index == this.size()) {
addLast(data);
return;
}
Node node = new Node(data);
//index前一个位置的地址
Node cur = searchIndex(index);
//开始插入
node.next = cur.next;
cur.next = node;
}
//寻找index的前一个位置的地址
public Node searchIndex(int index) {
if(index < 0 || index > this.size()) {
throw new RuntimeException("index位置不合法!");
}
Node cur = this.head;
while(index-1 != 0) {
cur = cur.next;
index--;
}
return cur;
}
//删除第一个关键字为key的节点
public void remove(int key,int data) {
if(this.head == null) {
return;
}
if(this.head.data == key) {
this.head = this.head.next;
return;
}
//找到节点的前一个节点
Node prev = searchPrev(key);
if(prev == null) {
System.out.println("没有这个节点");
return;
}
prev.next = prev.next.next;
}
//寻找节点的前一个结点
public Node searchPrev(int key) {
Node prev = this.head;
while(prev.next != null) {
if(prev.next.data == key) {
return prev;
}else{
return prev.next;
}
}
return null;
}
//清空单链表
public void clear(){
this.head = null;
}
}