聊聊LinkedList
不知道你们用过LinkedList没,对于LinkedList的印象我可能停留在2个地方:
1、java八股文中,比如ArryList和LinkedList的区别,ArrayList支持随机访问,能根据下标查询,但从中间插入或删除需要移动移动数组;LinkedList插入删除快,但不支持随机访问,而且占用内存比较大。HashMap底层运用了LinkedList拉链法解决Hash冲突......
2、leetCode的链表操作,如合并链表,反转链表,删除链表倒数第N个节点......
那么问题来了,LinkedList真的好用吗,我问了几个同事都说在工作中没用过LinkedList,基本上数组用ArrayList就能解决问题,连原作者在推特上也说自己写了也没用过
但是不用归不用,对于链表的简单操作和数据结构最好还是要了解熟悉,万一面试问到了或者机试考到了呢
简单链表操作
第一个接触链表简单题是合并两个有序列表,一开始是没啥想法..对链表操作不太熟悉,后面看了答案之后发现好像也不难,但是自己写又写不出来- -答案的思路是先建立一个头结点,比较两个链表节点哪个小就连接哪个节点,如果某个链表遍历完了,就连接另一个链表。
上面用的尾插法,通过node = node.next移动末尾,再用node.next = newNode插入,注意先用一个head标记头指针,不然无法找到他的头指针。
看过HashMap八股文应该知道jdk1.7多线程rehash会有循环列表问题,涉及到头插法,简单说一下头插法实现:
newNode.next = oldNode;
oldNode = newNode;
一开始我看代码的时候感觉头晕脑胀,怎么指来指去的?后面画了一个图后,逻辑就比较清晰明了
堆栈与队列
在看算法的时候发现堆栈与队列的实现方式也是很巧妙的,使用了头插法和尾插法的方式。
堆栈: 头插法添加元素
public class Stack<Item>
{
private Node first;//栈顶,最近添加的元素
private int N; //元素数量
private class Node{
Item item;
Node next;
}
public void push(Item item){
//栈顶添加元素
Node oldfirst = first;
first = new Node();
first.next = oldfirst;
N++;
}
public Item pop() {
//栈顶弹出元素
Item item = fist.item;
first = first.next;
N--;
return item;
}
}
队列: 尾插法添加元素,需要记录头结点和尾节点
public class Queue<Item>{
private Node first;//头结点
private Node last; //尾节点
private int n;
private class Node {
Item item;
Node next;
}
public void enqueue(Item item) {
Node oldlast =last;
last = new Node();
last.item = item;
last.next = null;
if(isEmpty()) first = last;
else oldlast.next = last;
N++;
}
}