SingleLinkedList类的实现
链表是一种线性表,但是其不是通过连续的内存空间来存储数据
public class SingleLinkedList {
static class ListNode{
public int val;
public ListNode next;
//下一个节点的地址
public ListNode(int val) {
this.val = val;
}
}
}
打印链表各节点
public void display() {
ListNode cur = head;
while (cur!=null) {
System.out.println(cur.val + " ");
cur = cur.next;
}
System.out.println();
}
获取链表长度
//得到单链表的长度
public int size() {
int count = 0;
ListNode cur = head;
while (cur != null) {
count ++;
cur = cur.next;
}
return count;
}
头插法和尾插法增加元素
//头插法
public void addFirst(int key) {
ListNode node = new ListNode(key);
node.next = head;
head =node;
}
//尾插法
public void addLast(int key) {
ListNode node = new ListNode(key);
ListNode cur = head;
if(cur == null) {
head = node;
return;
}
//找到链表的尾巴 注意是cur.next 不是cur
while (cur.next != null ){
cur = cur.next;
}
cur.next = node;
}
在指定位置插入时,需要找到指定位置index前一个节点
查询index前一个节点
// 找到index-1的节点
// return index-1 的地址
public ListNode findIndexSubOne(int index) {
ListNode cur = head;
while (index-1!=0) {
cur = cur.next;
index--;
}
return cur;
}
SingleLinkedList的增加
任意位置插入
//在指定index位置插入值为data的节点
public void addIndex(int index,int data) {
if(index < 0 || index > size()) {
System.out.println("index不合法");
return;
}
//头插情况
if(index == 0) {
addFirst(data);
return;
}
//尾插情况
if(index == size()) {
addLast(data);
return;
}
//在任意位置插入新元素(非头插尾插)
ListNode node = new ListNode(data);
ListNode cur = findIndexSubOne(index);
node.next = cur.next;
cur.next = node;
}
SingleLinkedList的删除
删除第一次出现关键字key的节点
//删除第一次 出现关键字 为key 的节点
public void removeOfKey(int key) {
if(this.head == null) {
System.out.println("此链表为空,不能进行删除! ");
return;
}
if(this.head.val == key) {
//判断 第一个节点是不是等于要删除的节点
this.head = this.head.next;
return;
}
ListNode cur = this.head;
while (cur.next != null) {
if(cur.next.val != key) {
ListNode del = cur.next;
cur.next = del.next;
return;
}
cur = cur.next;
}
}
删除所有值为key的结点
// 删除所有值为 key 的节点
public void removeAllKey(int key){
//单独处理头节点
if(this.head.val == key) {
head = head.next;
}
if(this.head == null) {
return;
}
ListNode cur = this.head.next;
ListNode prev = this.head;
while (cur!=null) {
if(cur.val==key) {
prev.next = cur.next;
cur = cur.next;
}else {
prev = cur;
cur = cur.next;
}
}
}
链表的增加(插入)和删除时间复杂度为O (1) , 但是找到插入(增加)和删除目标位置的时间复杂度O(N)
全部代码展示
public class SingleLinkedList {
static class ListNode{
public int val;
public ListNode next;
//下一个节点的地址
public ListNode(int val) {
this.val = val;
}
}
public ListNode head;
//表示当前链表的头节点
public void addList() {
ListNode node1 = new ListNode(6);
ListNode node2 = new ListNode(7);
ListNode node3 = new ListNode(8);
ListNode node4 = new ListNode(9);
ListNode node5 = new ListNode(10);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
this.head = node1;
}
public void display() {
ListNode cur = head;
while (cur!=null) {
System.out.println(cur.val + " ");
cur = cur.next;
}
System.out.println();
}
//得到单链表的长度
public int size() {
int count = 0;
ListNode cur = head;
while (cur != null) {
count ++;
cur = cur.next;
}
return count;
}
//查找是否包含关键字key是否在单链表当中
public boolean contains(int key) {
ListNode cur = head;
while (cur!=null) {
if(cur.val==key) {
return true;
}
cur = cur.next;
}
return false;
}
//头插法
public void addFirst(int key) {
ListNode node = new ListNode(key);
node.next = head;
head =node;
}
//尾插法
public void addLast(int key) {
ListNode node = new ListNode(key);
ListNode cur = head;
if(cur == null) {
head = node;
return;
}
//找到链表的尾巴 注意是cur.next 不是cur
while (cur.next != null ){
cur = cur.next;
}
cur.next = node;
}
//在指定index位置插入值为data的节点
public void addIndex(int index,int data) {
if(index < 0 || index > size()) {
System.out.println("index不合法");
return;
}
//头插情况
if(index == 0) {
addFirst(data);
return;
}
//尾插情况
if(index == size()) {
addLast(data);
return;
}
//在知道位置插入新元素(非头插尾插)
ListNode node = new ListNode(data);
ListNode cur = findIndexSubOne(index);
node.next = cur.next;
cur.next = node;
}
// 找到index-1的节点
// return index-1 的地址
public ListNode findIndexSubOne(int index) {
ListNode cur = head;
while (index-1!=0) {
cur = cur.next;
index--;
}
return cur;
}
//删除第一次 出现关键字 为key 的节点
public void removeOfKey(int key) {
if(this.head == null) {
System.out.println("此链表为空,不能进行删除! ");
return;
}
if(this.head.val == key) {
//判断 第一个节点是不是等于要删除的节点
this.head = this.head.next;
return;
}
ListNode cur = this.head;
while (cur.next != null) {
if(cur.next.val != key) {
ListNode del = cur.next;
cur.next = del.next;
return;
}
cur = cur.next;
}
}
// 删除所有值为 key 的节点
public void removeAllKey(int key){
//单独处理头节点
if(this.head.val == key) {
head = head.next;
}
if(this.head == null) {
return;
}
ListNode cur = this.head.next;
ListNode prev = this.head;
while (cur!=null) {
if(cur.val==key) {
prev.next = cur.next;
cur = cur.next;
}else {
prev = cur;
cur = cur.next;
}
}
}
//当我们 执行 clear 这个函数的时候,会将 这个链表 当中的所有节点回收
public void clear(){
/* 简单粗暴的做法
this.head = null;*/
ListNode cur = this.head;
ListNode curNext = null;
while (cur != null) {
curNext = cur.next;
cur.next = null;
cur = curNext;
}
//遍历每一个节点,通过curNext保存cur.next,在将每一个节点间的联系置为空NULL;
head = null;
}
}