什么是线性表:
具体实现:
Java
参考实现:ArrayList:
解析:
ArrayList内部有EMPTY_ELEMENTDATA 和DEFAULTCAPACITY_EMPTY_ELEMENTDATA 两个元素,连个元素的作用,及其区别: 这两个都是空数组
当 使用 DEFAULTCAPACITY_EMPTY_ELEMENTDATA 的时候,意味着 默认的容量为10
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
当add的时候,才会设置容量为10:
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
// 计算容量
private static int calculateCapacity(Object[] elementData, int minCapacity) {
// 如果是默认的空数组的话,则会将容量与最小值匹配取最大值
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
// 用于快速失败机制
modCount++;
// 当最小值容量大于当前元素的长度的时候就会发生扩容,并不是达到 1/2 就会扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
// 在老容量的基础上扩容 1半
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 同时,如果扩容之后的大小超过了最大限定的话,则会再扩容到最大值: Integer.MAX_VALUE
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 拷贝达到扩容效果
elementData = Arrays.copyOf(elementData, newCapacity);
}
问题:
是为了提升性能:
总结:
查找时间复杂度: O(n): 需要遍历匹配
插入的时间复杂度: O(1) 或者O(n) :
删除的时间复杂度同插入: O(1)或者O(n)
单向链表每个节点只有指针域和数据域,指针域指向下一个节点
@Data
public class MyLinkedList<T>
{
@Data
class ListNode<T>
{
private T data;
private ListNode<T> next;
public ListNode()
{
}
}
private ListNode<T> head;
private int size;
public MyLinkedList()
{
}
// 添加
public void add(T value)
{
ListNode<T> listNode = new ListNode<>();
listNode.setData(value);
if (this.head == null)
{
this.head = listNode;
} else
{
ListNode<T> tempNode = this.head;
while (tempNode.next != null)
{
tempNode = tempNode.getNext();
}
tempNode.next = listNode;
}
}
// 删除 节点,需要先连再断,所以需要保存上一个节点
public void remove(T value)
{
ListNode<T> tempNode = this.getHead();
while (tempNode != null)
{
if (null != tempNode.next && tempNode.next.getData().equals(value))
{
ListNode<T> prevNode = tempNode;
prevNode.setNext(tempNode.getNext());
tempNode.setNext(null);
break;
}else{
tempNode=tempNode.next;
}
}
}
// 查询
public boolean contains(T value)
{
ListNode<T> tempNode = this.getHead();
while (tempNode != null)
{
if (tempNode.getData().equals(value))
{
return true;
}
tempNode=tempNode.next;
}
return false;
}
}
type SingleLinkedListNode struct {
Data interface{}
Next *SingleLinkedListNode
}
type MySingleLinkedList struct {
Head *SingleLinkedListNode
Tail *SingleLinkedListNode
Size int
}
func (this *MySingleLinkedList) Add(value interface{}) error {
newNode := &SingleLinkedListNode{
Data: value,
}
if nil == this.Head {
this.Head = newNode
} else {
this.Tail.Next = newNode
}
this.Tail = newNode
return nil
}
func (this *MySingleLinkedList) Remove(value interface{}) error {
tempNode := this.Head
for nil != tempNode {
if nil != tempNode.Next && tempNode.Next.Data == value {
prevNode := tempNode
prevNode.Next = tempNode.Next
tempNode.Next = nil
}else{
tempNode=tempNode.Next
}
}
return nil
}
class MySingleLinkedListNode(object):
__slots__ = ('data', 'nextV')
def __init__(self):
self.data = None
self.nextV = None
def __str__(self):
return 'data=%s' % self.data
class MySingleLinkedList(object):
__slots__ = ('head', 'tail', 'size', 'cursor')
def __init__(self):
self.head = None
self.tail = self.head
self.cursor = 0
self.size = 0
def add(self, value):
newNode = MySingleLinkedListNode()
newNode.data = value
if self.head is None:
self.head = newNode
else:
self.tail.nextV = newNode
self.tail = newNode
self.size += 1
def remove(self, value):
tempNode = self.head
while tempNode is not None:
if tempNode.next is not None and tempNode.next.data == value:
prevNode = tempNode
prevNode.next = tempNode.next
tempNode.next = None
break
else:
tempNode = tempNode.next
def __iter__(self):
return self
def __next__(self):
i = 0
tempNode = self.head
while i < self.cursor and tempNode is not None and i < self.size:
i += 1
tempNode = tempNode.nextV
if self.cursor < self.size:
self.cursor += 1
return tempNode
def print(self):
tempNode = self.head
while tempNode is not None:
print(tempNode)
tempNode = tempNode.nextV
mys = MySingleLinkedList()
mys.add(1)
mys.add(2)
mys.print()
for v in mys:
if v is not None:
print(v)
双向链表指的是节点不仅连接着后继节点,也连接着前驱节点
源码解析:参考LinkedList
public boolean add(E e) {
linkLast(e);
return true;
}
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
添加采用的是尾插法,
删除:
public E remove() {
return removeFirst();
}
public E removeFirst() {
// 将首节点作为局部变量,减小生命周期
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return unlinkFirst(f);
}
private E unlinkFirst(Node<E> f) {
final E element = f.item;
// 保存下一个节点,这个节点作为之后的首节点
final Node<E> next = f.next;
f.item = null;
f.next = null; // help GC
first = next;
// 如果下一个节点为空,代表着整个list为空
if (next == null)
last = null;
else
// 不是双向循环链表,所以需要将前置节点置空
next.prev = null;
size--;
// 快速失败机制
modCount++;
return element;
}
删除,默认是删除的首节点
删除某个下标的节点:
public E remove(int index) {
checkElementIndex(index);
return unlink(node(index));
}
Node<E> node(int index) {
// assert isElementIndex(index);
// 如果下标小于一半,则从前往后
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
// 否则从后往前
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
// 断开链接,prev需要指向cur的next ,cur的next需要指向cur的prev
// 然后cur的next,prev全指向空
// 唯一需要注意的就是删除的是否是头节点或者是尾节点
E unlink(Node<E> x) {
// assert x != null;
final E element = x.item;
final Node<E> next = x.next;
final Node<E> prev = x.prev;
// 删除的是首节点
if (prev == null) {
first = next;
} else {
// 将prev的next指向cur的next
prev.next = next;
// 断开cur的next
x.prev = null;
}
// 删除的是尾节点
if (next == null) {
last = prev;
} else {
// 将next的prev指向cur的prev
next.prev = prev;
// 断开cur的next
x.next = null;
}
x.item = null;
size--;
modCount++;
return element;
}
Java实现:
@Data
public class MyDoubleLinkedList<T> implements Iterable<T>
{
@Override
public Iterator<T> iterator()
{
return new MyDlIterator();
}
@Data
class DoubleLinkedListNode<T>
{
private T data;
private DoubleLinkedListNode<T> prev;
private DoubleLinkedListNode<T> next;
}
private DoubleLinkedListNode<T> head;
private DoubleLinkedListNode<T> tail;
private int size;
public void add(T value)
{
DoubleLinkedListNode<T> newNode = new DoubleLinkedListNode<>();
newNode.setData(value);
linkLast(newNode);
}
private void linkLast(DoubleLinkedListNode<T> node)
{
final DoubleLinkedListNode<T> tail = this.tail;
if (this.head == null)
{
this.head = node;
} else
{
tail.next = node;
node.prev = tail;
}
this.tail = node;
this.size++;
}
// 将数据插入到指定位置中
public void insert(T value, int index)
{
// 校验index
if (!this.checkIndex(index)) throw new IndexOutOfBoundsException();
DoubleLinkedListNode<T> newNode = new DoubleLinkedListNode<>();
newNode.setData(value);
// 插入的时候需要 获取到 插入位置的节点Cur,cur 是newNode的下一个节点,以及上一个节点prev
// 并不需要减1,因为node持有prev的引用
DoubleLinkedListNode<T> tempNode = this.head;
for (int i = 0; i < index; i++)
{
tempNode = tempNode.next;
}
if (null != tempNode.prev)
{
tempNode.prev.next = newNode;
newNode.prev = tempNode.prev;
}
newNode.next = tempNode;
tempNode.prev = newNode;
this.size++;
}
// 删除指定位置的元素
public DoubleLinkedListNode<T> remove(int index)
{
if (!this.checkIndex(index)) throw new IndexOutOfBoundsException();
DoubleLinkedListNode<T> tempNode = this.head;
for (int i = 0; i < index; i++)
{
tempNode = tempNode.next;
}
final DoubleLinkedListNode<T> prev = tempNode.prev;
final DoubleLinkedListNode<T> cur = tempNode;
final DoubleLinkedListNode<T> next = tempNode.next;
if (prev != null)
{
prev.next = next;
tempNode.prev = null;
}
if (next != null)
{
next.prev = prev;
tempNode.next = null;
}
this.size--;
return cur;
}
class MyDlIterator<T> implements Iterator<T>
{
private int cursor;
@Override
public boolean hasNext()
{
return this.cursor < MyDoubleLinkedList.this.size;
}
@Override
public T next()
{
DoubleLinkedListNode<T> tempNode = (DoubleLinkedListNode<T>) MyDoubleLinkedList.this.head;
for (int i = 0; i < this.cursor; i++)
{
tempNode = tempNode.next;
}
this.cursor++;
return tempNode.data;
}
@Override
public void remove()
{
}
@Override
public void forEachRemaining(Consumer action)
{
}
}
private boolean checkIndex(int index)
{
if (index < 0 || index > this.size)
{
return false;
}
return true;
}
public static void main(String[] args)
{
MyDoubleLinkedList<Integer> myDoubleLinkedList = new MyDoubleLinkedList<>();
myDoubleLinkedList.add(1);
myDoubleLinkedList.add(2);
for (Integer integer : myDoubleLinkedList)
{
System.out.println(integer);
}
}
GoLang实现:
type MyDoubleLinkedListNode struct {
Data interface{}
Next *MyDoubleLinkedListNode
Prev *MyDoubleLinkedListNode
}
type MyDoubleLinkedList struct {
Head *MyDoubleLinkedListNode
Tail *MyDoubleLinkedListNode
Size int
}
func (this *MyDoubleLinkedList) Add(value interface{}) error {
newNode := &MyDoubleLinkedListNode{
Data: value,
}
return this.LinkLast(newNode)
}
func (this *MyDoubleLinkedList) LinkLast(node *MyDoubleLinkedListNode) error {
if this.Head == nil {
this.Head = node
} else {
this.Tail.Next = node
node.Prev = this.Tail
}
this.Tail = node
this.Size++
return nil
}
func (this *MyDoubleLinkedList) Insert(value interface{}, index int) error {
if e := this.checkIndex(index); nil != e {
return e
}
newNode := &MyDoubleLinkedListNode{
Data: value,
}
// 插入到末尾
if index == this.Size {
return this.LinkLast(newNode)
}
tNode := this.Head
for i := 0; i < index-1; i++ {
tNode = tNode.Next
}
prev := tNode.Prev
next := tNode
if nil != prev {
prev.Next = newNode
newNode.Prev = prev
} else {
// 说明是首节点
this.Head = newNode
}
if nil != next {
next.Prev = newNode
} else {
// 说明是尾节点
this.Tail = newNode
}
newNode.Next = next
this.Size++
return nil
}
func (this *MyDoubleLinkedList) checkIndex(index int) error {
if index < 0 || index > this.Size {
return errors.New("index out of range ,index begin with 0")
}
return nil
}
func (this *MyDoubleLinkedList) Remove(index int) error {
if e := this.checkIndex(index); nil != e {
return e
}
tNode := this.Head
for i := 0; i < index; i++ {
tNode = tNode.Next
}
prev := tNode.Prev
next := tNode.Next
prev.Next = next
next.Prev = prev
tNode.Next, tNode.Prev = nil, nil
this.Size--
return nil
}
func (this *MyDoubleLinkedList) Foreach() {
tNode := this.Head
for nil != tNode {
fmt.Println(tNode.Data)
tNode = tNode.Next
}
}
Python实现:
class MyDoubleLinkedListNode(object):
__slots__ = ('data', 'next', 'prev')
def __str__(self):
print('value is %s' % self.data)
class MyDoubleLinkedList(object):
__slots__ = ('head', 'tail', 'size')
def __init__(self):
self.head = None
self.tail = None
self.size = 0
def add(self, value):
newNode = MyDoubleLinkedListNode()
newNode.data = value
if self.head is None:
self.head = newNode
else:
self.tail.next = newNode
newNode.prev = self.tail
self.tail = newNode
self.size += 1
def insert(self, index, value):
newNode = MyDoubleLinkedListNode()
newNode.data = value
self.check_index(index)
if index == self.size:
self.link_last(newNode)
else:
self.link_before(index, newNode)
def link_last(self, node):
if self.head is None:
self.head = node
else:
node.prev = self.tail
self.tail.next = node
self.tail = node
self.size += 1
def link_before(self, index, node):
i = 0
tNode = self.head
while i < index:
tNode = tNode.next
i += 1
prev = tNode.prev
if prev is not None:
prev.next = node
node.prev = prev
else:
self.head = node
if tNode is not None:
node.next = tNode
tNode.prev = node
else:
self.tail = node
self.size += 1
def remove(self, index):
self.check_index(index)
i = 0
tNode = self.head
while i < index:
i += 1
tNode = tNode.next
prev = tNode.prev
next = tNode.next
cur = tNode
if prev is not None:
prev.next = next
else:
# 说明是头节点
self.head = next
if next is not None:
next.prev = prev
else:
# 说明是尾节点
self.tail = next
cur.next = None
cur.prev = None
self.size -= 1
def check_index(self, index):
if index < 0 or index > self.size:
raise IndexError('index out of range')
def __iter__(self):
itr = MyDoubleLinkedList.InternalIterator(self)
return itr
class InternalIterator(object):
cursor = 0
def __init__(self, outter):
self.outter = outter
def __next__(self):
if self.cursor >= self.outter.size:
raise StopIteration
else:
i = 0
tNode = self.outter.head
while i < self.cursor:
tNode = tNode.next
i += 1
self.cursor += 1
return tNode
myD = MyDoubleLinkedList()
myD.add(1)
myD.add(2)
myD.add(3)
for v in myD:
if v is not None:
print(v.data)
myD.insert(2, 4)
for v in myD:
print(v.data)