1. ArrayList的缺陷
ArrayList底层使用数组来存储元素
由于其底层是一段连续空间,当在ArrayList任意位置插入或者删除元素时,就需要将后序元素整体往前或者往后 搬移,时间复杂度为O(n),效率比较低。因此ArrayList不适合做任意位置插入和删除比较多的场景。
因此:java 集合中又引入了LinkedList,即链表结构。
2. 链表
链表的概念及结构
链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的 。
注意:
1.从上图可看出,链式结构在逻辑上是连续的,但是在物理上不一定连续
2.现实中的结点一般都是从堆上申请出来的
3.从堆上申请的空间,是按照一定的策略来分配的,两次申请的空间可能连续,也可能不连续
1. 单向或者双向
2. 带头或者不带头
3. 循环或者非循环
3 模拟LinkedList的实现
我们先来定义一些数据:
public class MySingleLinkedList {class ListNode{public int val;public ListNode nest;public ListNode(int val) {this.val = val;}}public ListNode head;//代表链表头节点
}
如果想要全部遍历完 那么 head != null而不是head.next != null
那样会少遍历最后一个值。
1头插法:
public void addFirst(int val){ListNode node = new ListNode(val);node.next = head;head = node;
2.尾插法:
public void addLast(int val) {ListNode node = new ListNode(val);if(head == null) {head = node;return;}ListNode cur = head;while (cur.next != null) {cur = cur.next;}cur.next = node;}
3任意位置插入:
public void addIndex(int index,int val) {//1.判断index的合法性try {checkIndex(index);}catch (IndexNotLegalException e) {e.printStackTrace();}//2.index == 0 || index == size()if(index == 0) {addFirst(val);return;}if(index == size()) {addLast(val);return;}//3. 找到index的前一个位置ListNode cur = findIndexSubOne(index);//4. 进行连接ListNode node = new ListNode(val);node.next = cur.next;cur.next = node;}private ListNode findIndexSubOne(int index) {int count = 0;ListNode cur = head;while (count != index-1) {cur = cur.next;count++;}return cur;}
4查找是否包含关键字val是否在单链表当中
public boolean contains(int val) {ListNode cur = head;while (cur != null) {if(cur.val == val) {return true;}cur = cur.next;}return false;}
5删除出现一次关键字为val的节点
public void remove(int val){if(head == null){return;}if (head.val==val){head = head.next;return;}ListNode cur = head;while (cur.next != null){if (cur.next.val==val){ListNode del =cur.next;cur.next=del.next;}cur=cur.next;}}
6删除所有值为key的节点
如果要删的是head.val,可以使代码走完在走一遍就行 或者把if改成while语句。
public void removeAllKey(int val) {//1. 判空if(this.head == null) {return;}//2. 定义prev 和 curListNode prev = head;ListNode cur = head.next;//3.开始判断并且删除while(cur != null) {if(cur.val == val) {prev.next = cur.next;//cur = cur.next;}else {prev = cur;//prev = prev.next;//cur = cur.next;}cur = cur.next;}//4.处理头节点if(head.val == val) {head = head.next;}}
7 清空链表
public void clear() {//head = null;ListNode cur = head;while (cur != null) {ListNode curN = cur.next;//cur.val = null;cur.next = null;cur = curN;}head = null;}