"你笑的次数越多越好,因为你只有用笑才能不怀恶意地消灭罪恶。"
作者:Mylvzi
文章主要内容:数据结构之单链表的模拟实现
MyArrayList
/**
* Created with IntelliJ IDEA.
* Description:
* User: 绿字
* Date: 2023-10-16
* Time: 19:37
*/
public class MySingleList {
// 定义为内部类
static class ListNode {
public int data;// 数据域
public ListNode next;// 指针域 默认是null
public ListNode(int data) {
this.data = data;
}
}
// 对于整个链表来说,只需一个head即可
public ListNode head;
// 创建一个单链表(穷举法)
public void createList() {
ListNode node1 = new ListNode(12);
ListNode node2 = new ListNode(23);
ListNode node3 = new ListNode(34);
ListNode node4 = new ListNode(45);
ListNode node5 = new ListNode(56);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
this.head = node1;
}
// 打印链表
public void display() {
// 保持head 不动 重新赋值给cur
ListNode cur = head;
while (cur != null) {
System.out.print(cur.data+ " ");
cur = cur.next;
}
System.out.println();
}
/**
* 从指定位置打印
*/
public void display(ListNode newHead) {
// 保持head 不动 重新赋值给cur
ListNode cur = newHead;
while (cur != null) {
System.out.print(cur.data+ " ");
cur = cur.next;
}
System.out.println();
}
// 返回链表长度
public int size() {
int cnt = 0;
ListNode cur = head;
while (cur != null) {
cnt++;
cur = cur.next;
}
return cnt;
}
// 判断是否包含数据域为key的结点
public boolean contains(int key) {
ListNode cur = head;
while (cur != null) {
if(cur.data == key) {
return true;
}
cur = cur.next;
}
return false;
}
// 头插
public void addFirst(int data) {
ListNode newhead = new ListNode(data);
newhead.next = head;
head = newhead;
}
// 尾插
public void addTail(int data) {
ListNode newtail = new ListNode(data);
ListNode cur = head;
// 注意如果链表为空的时候不能访问其next 要单独处理
if (cur == null) {
head = newtail;
return;// 一定要return,去结束异常
}
while(cur.next != null) {
cur = cur.next;
}
cur.next = newtail;
}
// 在Index位置插入
public void addIndex(int index,int data){
// 检查Index合法性
if(index < 0 || index > size()) {
throw new IndexOutOfBoundException("位置异常");
}
if(index == 0) {
addFirst(data);
return;
}
if(index == size()) {
addTail(data);
return;
}
// 让cur走到index的前驱结点
ListNode newnode = new ListNode(data);
ListNode cur = findPrevOfIndex(index);
newnode.next = cur.next;
cur.next = newnode;
}
// 将找前驱结点包装成一个方法 找到index位置的前一个结点 让cur走index-1步
private ListNode findPrevOfIndex(int index) {
ListNode cur = head;
while (index != 1) {
cur = cur.next;
index--;
}
return cur;
}
// 删除值为key的结点(第一次出现的)
public void remove(int key) {
if (head == null) {
return;
}
// 单独删除头节点 因为其没有前驱节点 不是只有一个节点
if (head.data == key) {
head = head.next;
return;
}
// 先找前驱节点
ListNode cur = findPrevOfKey(key);
if (cur == null) {
System.out.println("未找到你要删除的结点");
return;
}
cur.next = cur.next.next;
// ListNode del = cur.next;
// cur.next = del.next;
}
// 找到数据域为key的结点的前一个结点
private ListNode findPrevOfKey(int key) {
ListNode cur = head;
while (cur.next != null) {
if (cur.next.data == key) {
return cur;
}
cur = cur.next;
}
// 未找到该节点
return null;
}
//
public void removeAll(int key) {
if (head == null) {
return;
}
ListNode prev = head;
ListNode cur = head.next;
while (cur != null) {
if (head.data == key) {
head = head.next;
// 此处不需要return
}
// 等于key
if(cur.data == key) {
prev.next = cur.next;
cur = prev.next;
continue;// 一定要添加一个continue,否则会与下面的代码重复
}
prev = prev.next;
cur = cur.next;
}
}
public void clear() {
this.head = null;
}
public ListNode reverseList() {
// 当链表为空时,或者只有一个节点(此时不需要反转了)直接返回即可
if(head == null) return head;
if(head.next == null) return head;
ListNode cur = head.next;
// 要给最初的head的next置空,否则会成环
head.next = null;
while(cur != null) {
ListNode curNext = cur.next;
cur.next = head;
head = cur;
cur = curNext;
}
return head;
}
}
异常
public class IndexOutOfBoundException extends RuntimeException{
public IndexOutOfBoundException(String message) {
super(message);
}
}
测试类:
/**
* Created with IntelliJ IDEA.
* Description:
* User: 绿字
* Date: 2023-10-16
* Time: 19:41
*/
public class SingleListTest {
public static void main(String[] args) {
MySingleList mySingleList = new MySingleList();
// mySingleList.createList();
mySingleList.addFirst(1);
mySingleList.addFirst(2);
mySingleList.addFirst(3);
mySingleList.addFirst(4);
mySingleList.addFirst(5);
mySingleList.display();
System.out.println("=============================");
MySingleList.ListNode newHead = mySingleList.reverseList();
mySingleList.display(newHead);
/* mySingleList.addTail(5);
mySingleList.addTail(5);
mySingleList.addTail(5);
mySingleList.addTail(5);
mySingleList.addTail(5);
mySingleList.addTail(5);
mySingleList.display();
System.out.println();
// mySingleList.removeAll(5);
mySingleList.display();*/
// mySingleList.addIndex(0,999);
// mySingleList.remove(1);
// mySingleList.remove(999);
// mySingleList.addTail(999999);
// mySingleList.display();
// mySingleList.addTail(199);
//
// mySingleList.addIndex(1,12);
// mySingleList.addIndex(0,999999999);
// mySingleList.addIndex(-1,12);
// mySingleList.display();
/* mySingleList.display();
System.out.println(mySingleList.size());
System.out.println(mySingleList.contains(12));
System.out.println(mySingleList.contains(1));*/
}
}