fork 自 sduonline/sc-resources
增加淘宝群内容,修改部分文件组织
此提交包含在:
@@ -0,0 +1,56 @@
|
||||
package com.mj;
|
||||
|
||||
public abstract class AbstractList<E> implements List<E> {
|
||||
/**
|
||||
* 元素的数量
|
||||
*/
|
||||
protected int size;
|
||||
/**
|
||||
* 元素的数量
|
||||
* @return
|
||||
*/
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为空
|
||||
* @return
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return size == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否包含某个元素
|
||||
* @param element
|
||||
* @return
|
||||
*/
|
||||
public boolean contains(E element) {
|
||||
return indexOf(element) != ELEMENT_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加元素到尾部
|
||||
* @param element
|
||||
*/
|
||||
public void add(E element) {
|
||||
add(size, element);
|
||||
}
|
||||
|
||||
protected void outOfBounds(int index) {
|
||||
throw new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
|
||||
}
|
||||
|
||||
protected void rangeCheck(int index) {
|
||||
if (index < 0 || index >= size) {
|
||||
outOfBounds(index);
|
||||
}
|
||||
}
|
||||
|
||||
protected void rangeCheckForAdd(int index) {
|
||||
if (index < 0 || index > size) {
|
||||
outOfBounds(index);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,154 @@
|
||||
package com.mj;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class ArrayList<E> extends AbstractList<E> {
|
||||
/**
|
||||
* 所有的元素
|
||||
*/
|
||||
private E[] elements;
|
||||
private static final int DEFAULT_CAPACITY = 10;
|
||||
|
||||
public ArrayList(int capaticy) {
|
||||
capaticy = (capaticy < DEFAULT_CAPACITY) ? DEFAULT_CAPACITY : capaticy;
|
||||
elements = (E[]) new Object[capaticy];
|
||||
}
|
||||
|
||||
public ArrayList() {
|
||||
this(DEFAULT_CAPACITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除所有元素
|
||||
*/
|
||||
public void clear() {
|
||||
for (int i = 0; i < size; i++) {
|
||||
elements[i] = null;
|
||||
}
|
||||
size = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取index位置的元素
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
public E get(int index) { // O(1)
|
||||
rangeCheck(index);
|
||||
|
||||
return elements[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置index位置的元素
|
||||
* @param index
|
||||
* @param element
|
||||
* @return 原来的元素ֵ
|
||||
*/
|
||||
public E set(int index, E element) { // O(1)
|
||||
rangeCheck(index);
|
||||
|
||||
E old = elements[index];
|
||||
elements[index] = element;
|
||||
return old;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在index位置插入一个元素
|
||||
* @param index
|
||||
* @param element
|
||||
*/
|
||||
public void add(int index, E element) {
|
||||
/*
|
||||
* 最好:O(1)
|
||||
* 最坏:O(n)
|
||||
* 平均:O(n)
|
||||
*/
|
||||
rangeCheckForAdd(index);
|
||||
|
||||
ensureCapacity(size + 1);
|
||||
|
||||
for (int i = size; i > index; i--) {
|
||||
elements[i] = elements[i - 1];
|
||||
}
|
||||
elements[index] = element;
|
||||
size++;
|
||||
} // size是数据规模
|
||||
|
||||
/**
|
||||
* 删除index位置的元素
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
public E remove(int index) {
|
||||
/*
|
||||
* 最好:O(1)
|
||||
* 最坏:O(n)
|
||||
* 平均:O(n)
|
||||
*/
|
||||
rangeCheck(index);
|
||||
|
||||
E old = elements[index];
|
||||
for (int i = index + 1; i < size; i++) {
|
||||
elements[i - 1] = elements[i];
|
||||
}
|
||||
elements[--size] = null;
|
||||
return old;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看元素的索引
|
||||
* @param element
|
||||
* @return
|
||||
*/
|
||||
public int indexOf(E element) {
|
||||
if (element == null) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (elements[i] == null) return i;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (element.equals(elements[i])) return i;
|
||||
}
|
||||
}
|
||||
return ELEMENT_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保证要有capacity的容量
|
||||
* @param capacity
|
||||
*/
|
||||
private void ensureCapacity(int capacity) {
|
||||
int oldCapacity = elements.length;
|
||||
if (oldCapacity >= capacity) return;
|
||||
|
||||
// 新容量为旧容量的1.5倍
|
||||
int newCapacity = oldCapacity + (oldCapacity >> 1);
|
||||
E[] newElements = (E[]) new Object[newCapacity];
|
||||
for (int i = 0; i < size; i++) {
|
||||
newElements[i] = elements[i];
|
||||
}
|
||||
elements = newElements;
|
||||
|
||||
System.out.println(oldCapacity + "扩容为" + newCapacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
// size=3, [99, 88, 77]
|
||||
StringBuilder string = new StringBuilder();
|
||||
string.append("size=").append(size).append(", [");
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (i != 0) {
|
||||
string.append(", ");
|
||||
}
|
||||
|
||||
string.append(elements[i]);
|
||||
|
||||
// if (i != size - 1) {
|
||||
// string.append(", ");
|
||||
// }
|
||||
}
|
||||
string.append("]");
|
||||
return string.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,189 @@
|
||||
package com.mj;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
/**
|
||||
* 有动态缩容操作
|
||||
* @author MJ Lee
|
||||
*
|
||||
* @param <E>
|
||||
*/
|
||||
public class ArrayList2<E> extends AbstractList<E> {
|
||||
/**
|
||||
* 所有的元素
|
||||
*/
|
||||
private E[] elements;
|
||||
private static final int DEFAULT_CAPACITY = 10;
|
||||
|
||||
public ArrayList2(int capaticy) {
|
||||
capaticy = (capaticy < DEFAULT_CAPACITY) ? DEFAULT_CAPACITY : capaticy;
|
||||
elements = (E[]) new Object[capaticy];
|
||||
}
|
||||
|
||||
public ArrayList2() {
|
||||
this(DEFAULT_CAPACITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除所有元素
|
||||
*/
|
||||
public void clear() {
|
||||
for (int i = 0; i < size; i++) {
|
||||
elements[i] = null;
|
||||
}
|
||||
size = 0;
|
||||
|
||||
// 仅供参考
|
||||
if (elements != null && elements.length > DEFAULT_CAPACITY) {
|
||||
elements = (E[]) new Object[DEFAULT_CAPACITY];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取index位置的元素
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
public E get(int index) { // O(1)
|
||||
rangeCheck(index);
|
||||
|
||||
return elements[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置index位置的元素
|
||||
* @param index
|
||||
* @param element
|
||||
* @return 原来的元素ֵ
|
||||
*/
|
||||
public E set(int index, E element) { // O(1)
|
||||
rangeCheck(index);
|
||||
|
||||
E old = elements[index];
|
||||
elements[index] = element;
|
||||
return old;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在index位置插入一个元素
|
||||
* @param index
|
||||
* @param element
|
||||
*/
|
||||
public void add(int index, E element) {
|
||||
/*
|
||||
* 最好:O(1)
|
||||
* 最坏:O(n)
|
||||
* 平均:O(n)
|
||||
*/
|
||||
rangeCheckForAdd(index);
|
||||
|
||||
ensureCapacity(size + 1);
|
||||
|
||||
for (int i = size; i > index; i--) {
|
||||
elements[i] = elements[i - 1];
|
||||
}
|
||||
elements[index] = element;
|
||||
size++;
|
||||
} // size是数据规模
|
||||
|
||||
/**
|
||||
* 删除index位置的元素
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
public E remove(int index) {
|
||||
/*
|
||||
* 最好:O(1)
|
||||
* 最坏:O(n)
|
||||
* 平均:O(n)
|
||||
*/
|
||||
rangeCheck(index);
|
||||
|
||||
E old = elements[index];
|
||||
for (int i = index + 1; i < size; i++) {
|
||||
elements[i - 1] = elements[i];
|
||||
}
|
||||
elements[--size] = null;
|
||||
|
||||
trim();
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看元素的索引
|
||||
* @param element
|
||||
* @return
|
||||
*/
|
||||
public int indexOf(E element) {
|
||||
if (element == null) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (elements[i] == null) return i;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (element.equals(elements[i])) return i;
|
||||
}
|
||||
}
|
||||
return ELEMENT_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保证要有capacity的容量
|
||||
* @param capacity
|
||||
*/
|
||||
private void ensureCapacity(int capacity) {
|
||||
int oldCapacity = elements.length;
|
||||
if (oldCapacity >= capacity) return;
|
||||
|
||||
// 新容量为旧容量的1.5倍
|
||||
int newCapacity = oldCapacity + (oldCapacity >> 1);
|
||||
|
||||
// 新容量为旧容量的2倍
|
||||
// int newCapacity = oldCapacity << 1;
|
||||
E[] newElements = (E[]) new Object[newCapacity];
|
||||
for (int i = 0; i < size; i++) {
|
||||
newElements[i] = elements[i];
|
||||
}
|
||||
elements = newElements;
|
||||
|
||||
System.out.println(oldCapacity + "扩容为" + newCapacity);
|
||||
}
|
||||
|
||||
private void trim() {
|
||||
// 30
|
||||
int oldCapacity = elements.length;
|
||||
// 15
|
||||
int newCapacity = oldCapacity >> 1;
|
||||
if (size > (newCapacity) || oldCapacity <= DEFAULT_CAPACITY) return;
|
||||
|
||||
// 剩余空间还很多
|
||||
E[] newElements = (E[]) new Object[newCapacity];
|
||||
for (int i = 0; i < size; i++) {
|
||||
newElements[i] = elements[i];
|
||||
}
|
||||
elements = newElements;
|
||||
|
||||
System.out.println(oldCapacity + "缩容为" + newCapacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
// size=3, [99, 88, 77]
|
||||
StringBuilder string = new StringBuilder();
|
||||
string.append("size=").append(size).append(", [");
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (i != 0) {
|
||||
string.append(", ");
|
||||
}
|
||||
|
||||
string.append(elements[i]);
|
||||
|
||||
// if (i != size - 1) {
|
||||
// string.append(", ");
|
||||
// }
|
||||
}
|
||||
string.append("]");
|
||||
return string.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
package com.mj;
|
||||
|
||||
public class Asserts {
|
||||
public static void test(boolean value) {
|
||||
try {
|
||||
if (!value) throw new Exception("测试未通过");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,175 @@
|
||||
package com.mj;
|
||||
|
||||
import com.mj.AbstractList;
|
||||
|
||||
public class LinkedList<E> extends AbstractList<E> {
|
||||
private Node<E> first;
|
||||
private Node<E> last;
|
||||
|
||||
private static class Node<E> {
|
||||
E element;
|
||||
Node<E> prev;
|
||||
Node<E> next;
|
||||
public Node(Node<E> prev, E element, Node<E> next) {
|
||||
this.prev = prev;
|
||||
this.element = element;
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (prev != null) {
|
||||
sb.append(prev.element);
|
||||
} else {
|
||||
sb.append("null");
|
||||
}
|
||||
|
||||
sb.append("_").append(element).append("_");
|
||||
|
||||
if (next != null) {
|
||||
sb.append(next.element);
|
||||
} else {
|
||||
sb.append("null");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
size = 0;
|
||||
first = null;
|
||||
last = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E get(int index) {
|
||||
return node(index).element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E set(int index, E element) {
|
||||
Node<E> node = node(index);
|
||||
E old = node.element;
|
||||
node.element = element;
|
||||
return old;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, E element) {
|
||||
rangeCheckForAdd(index);
|
||||
|
||||
// size == 0
|
||||
// index == 0
|
||||
if (index == size) { // 往最后面添加元素
|
||||
Node<E> oldLast = last;
|
||||
last = new Node<>(oldLast, element, null);
|
||||
if (oldLast == null) { // 这是链表添加的第一个元素
|
||||
first = last;
|
||||
} else {
|
||||
oldLast.next = last;
|
||||
}
|
||||
} else {
|
||||
Node<E> next = node(index);
|
||||
Node<E> prev = next.prev;
|
||||
Node<E> node = new Node<>(prev, element, next);
|
||||
next.prev = node;
|
||||
|
||||
if (prev == null) { // index == 0
|
||||
first = node;
|
||||
} else {
|
||||
prev.next = node;
|
||||
}
|
||||
}
|
||||
|
||||
size++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E remove(int index) {
|
||||
rangeCheck(index);
|
||||
|
||||
Node<E> node = node(index);
|
||||
Node<E> prev = node.prev;
|
||||
Node<E> next = node.next;
|
||||
|
||||
if (prev == null) { // index == 0
|
||||
first = next;
|
||||
} else {
|
||||
prev.next = next;
|
||||
}
|
||||
|
||||
if (next == null) { // index == size - 1
|
||||
last = prev;
|
||||
} else {
|
||||
next.prev = prev;
|
||||
}
|
||||
|
||||
size--;
|
||||
return node.element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(E element) {
|
||||
if (element == null) {
|
||||
Node<E> node = first;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (node.element == null) return i;
|
||||
|
||||
node = node.next;
|
||||
}
|
||||
} else {
|
||||
Node<E> node = first;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (element.equals(node.element)) return i;
|
||||
|
||||
node = node.next;
|
||||
}
|
||||
}
|
||||
return ELEMENT_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取index位置对应的节点对象
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
private Node<E> node(int index) {
|
||||
rangeCheck(index);
|
||||
|
||||
if (index < (size >> 1)) {
|
||||
Node<E> node = first;
|
||||
for (int i = 0; i < index; i++) {
|
||||
node = node.next;
|
||||
}
|
||||
return node;
|
||||
} else {
|
||||
Node<E> node = last;
|
||||
for (int i = size - 1; i > index; i--) {
|
||||
node = node.prev;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder string = new StringBuilder();
|
||||
string.append("size=").append(size).append(", [");
|
||||
Node<E> node = first;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (i != 0) {
|
||||
string.append(", ");
|
||||
}
|
||||
|
||||
string.append(node);
|
||||
|
||||
node = node.next;
|
||||
}
|
||||
string.append("]");
|
||||
return string.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,70 @@
|
||||
package com.mj;
|
||||
|
||||
public interface List<E> {
|
||||
static final int ELEMENT_NOT_FOUND = -1;
|
||||
/**
|
||||
* 清除所有元素
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* 元素的数量
|
||||
* @return
|
||||
*/
|
||||
int size();
|
||||
|
||||
/**
|
||||
* 是否为空
|
||||
* @return
|
||||
*/
|
||||
boolean isEmpty();
|
||||
|
||||
/**
|
||||
* 是否包含某个元素
|
||||
* @param element
|
||||
* @return
|
||||
*/
|
||||
boolean contains(E element);
|
||||
|
||||
/**
|
||||
* 添加元素到尾部
|
||||
* @param element
|
||||
*/
|
||||
void add(E element);
|
||||
|
||||
/**
|
||||
* 获取index位置的元素
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
E get(int index);
|
||||
|
||||
/**
|
||||
* 设置index位置的元素
|
||||
* @param index
|
||||
* @param element
|
||||
* @return 原来的元素ֵ
|
||||
*/
|
||||
E set(int index, E element);
|
||||
|
||||
/**
|
||||
* 在index位置插入一个元素
|
||||
* @param index
|
||||
* @param element
|
||||
*/
|
||||
void add(int index, E element);
|
||||
|
||||
/**
|
||||
* 删除index位置的元素
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
E remove(int index);
|
||||
|
||||
/**
|
||||
* 查看元素的索引
|
||||
* @param element
|
||||
* @return
|
||||
*/
|
||||
int indexOf(E element);
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
package com.mj;
|
||||
|
||||
import com.mj.circle.CircleLinkedList;
|
||||
|
||||
public class Main {
|
||||
|
||||
static void testList(List<Integer> list) {
|
||||
list.add(11);
|
||||
list.add(22);
|
||||
list.add(33);
|
||||
list.add(44);
|
||||
|
||||
list.add(0, 55); // [55, 11, 22, 33, 44]
|
||||
list.add(2, 66); // [55, 11, 66, 22, 33, 44]
|
||||
list.add(list.size(), 77); // [55, 11, 66, 22, 33, 44, 77]
|
||||
|
||||
list.remove(0); // [11, 66, 22, 33, 44, 77]
|
||||
list.remove(2); // [11, 66, 33, 44, 77]
|
||||
list.remove(list.size() - 1); // [11, 66, 33, 44]
|
||||
|
||||
Asserts.test(list.indexOf(44) == 3);
|
||||
Asserts.test(list.indexOf(22) == List.ELEMENT_NOT_FOUND);
|
||||
Asserts.test(list.contains(33));
|
||||
Asserts.test(list.get(0) == 11);
|
||||
Asserts.test(list.get(1) == 66);
|
||||
Asserts.test(list.get(list.size() - 1) == 44);
|
||||
|
||||
System.out.println(list);
|
||||
}
|
||||
|
||||
static void josephus() {
|
||||
CircleLinkedList<Integer> list = new CircleLinkedList<>();
|
||||
for (int i = 1; i <= 8; i++) {
|
||||
list.add(i);
|
||||
}
|
||||
|
||||
// 指向头结点(指向1)
|
||||
list.reset();
|
||||
|
||||
while (!list.isEmpty()) {
|
||||
list.next();
|
||||
list.next();
|
||||
System.out.println(list.remove());
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
josephus();
|
||||
|
||||
// testList(new ArrayList<>());
|
||||
// testList(new LinkedList<>());
|
||||
|
||||
|
||||
// testList(new SingleCircleLinkedList<>());
|
||||
|
||||
// testList(new CircleLinkedList<>());
|
||||
|
||||
/*
|
||||
* gc root对象
|
||||
* 1> 被局部变量指向的对象
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,208 @@
|
||||
package com.mj.circle;
|
||||
|
||||
import com.mj.AbstractList;
|
||||
|
||||
public class CircleLinkedList<E> extends AbstractList<E> {
|
||||
private Node<E> first;
|
||||
private Node<E> last;
|
||||
private Node<E> current;
|
||||
|
||||
private static class Node<E> {
|
||||
E element;
|
||||
Node<E> prev;
|
||||
Node<E> next;
|
||||
public Node(Node<E> prev, E element, Node<E> next) {
|
||||
this.prev = prev;
|
||||
this.element = element;
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (prev != null) {
|
||||
sb.append(prev.element);
|
||||
} else {
|
||||
sb.append("null");
|
||||
}
|
||||
|
||||
sb.append("_").append(element).append("_");
|
||||
|
||||
if (next != null) {
|
||||
sb.append(next.element);
|
||||
} else {
|
||||
sb.append("null");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
current = first;
|
||||
}
|
||||
|
||||
public E next() {
|
||||
if (current == null) return null;
|
||||
|
||||
current = current.next;
|
||||
return current.element;
|
||||
}
|
||||
|
||||
public E remove() {
|
||||
if (current == null) return null;
|
||||
|
||||
Node<E> next = current.next;
|
||||
E element = remove(current);
|
||||
if (size == 0) {
|
||||
current = null;
|
||||
} else {
|
||||
current = next;
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
size = 0;
|
||||
first = null;
|
||||
last = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E get(int index) {
|
||||
return node(index).element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E set(int index, E element) {
|
||||
Node<E> node = node(index);
|
||||
E old = node.element;
|
||||
node.element = element;
|
||||
return old;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, E element) {
|
||||
rangeCheckForAdd(index);
|
||||
|
||||
// size == 0
|
||||
// index == 0
|
||||
if (index == size) { // 往最后面添加元素
|
||||
Node<E> oldLast = last;
|
||||
last = new Node<>(oldLast, element, first);
|
||||
if (oldLast == null) { // 这是链表添加的第一个元素
|
||||
first = last;
|
||||
first.next = first;
|
||||
first.prev = first;
|
||||
} else {
|
||||
oldLast.next = last;
|
||||
first.prev = last;
|
||||
}
|
||||
} else {
|
||||
Node<E> next = node(index);
|
||||
Node<E> prev = next.prev;
|
||||
Node<E> node = new Node<>(prev, element, next);
|
||||
next.prev = node;
|
||||
prev.next = node;
|
||||
|
||||
if (next == first) { // index == 0
|
||||
first = node;
|
||||
}
|
||||
}
|
||||
|
||||
size++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E remove(int index) {
|
||||
rangeCheck(index);
|
||||
return remove(node(index));
|
||||
}
|
||||
|
||||
private E remove(Node<E> node) {
|
||||
if (size == 1) {
|
||||
first = null;
|
||||
last = null;
|
||||
} else {
|
||||
Node<E> prev = node.prev;
|
||||
Node<E> next = node.next;
|
||||
prev.next = next;
|
||||
next.prev = prev;
|
||||
|
||||
if (node == first) { // index == 0
|
||||
first = next;
|
||||
}
|
||||
|
||||
if (node == last) { // index == size - 1
|
||||
last = prev;
|
||||
}
|
||||
}
|
||||
|
||||
size--;
|
||||
return node.element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(E element) {
|
||||
if (element == null) {
|
||||
Node<E> node = first;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (node.element == null) return i;
|
||||
|
||||
node = node.next;
|
||||
}
|
||||
} else {
|
||||
Node<E> node = first;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (element.equals(node.element)) return i;
|
||||
|
||||
node = node.next;
|
||||
}
|
||||
}
|
||||
return ELEMENT_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取index位置对应的节点对象
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
private Node<E> node(int index) {
|
||||
rangeCheck(index);
|
||||
|
||||
if (index < (size >> 1)) {
|
||||
Node<E> node = first;
|
||||
for (int i = 0; i < index; i++) {
|
||||
node = node.next;
|
||||
}
|
||||
return node;
|
||||
} else {
|
||||
Node<E> node = last;
|
||||
for (int i = size - 1; i > index; i--) {
|
||||
node = node.prev;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder string = new StringBuilder();
|
||||
string.append("size=").append(size).append(", [");
|
||||
Node<E> node = first;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (i != 0) {
|
||||
string.append(", ");
|
||||
}
|
||||
|
||||
string.append(node);
|
||||
|
||||
node = node.next;
|
||||
}
|
||||
string.append("]");
|
||||
return string.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,135 @@
|
||||
package com.mj.circle;
|
||||
|
||||
import com.mj.AbstractList;
|
||||
|
||||
public class SingleCircleLinkedList<E> extends AbstractList<E> {
|
||||
private Node<E> first;
|
||||
|
||||
private static class Node<E> {
|
||||
E element;
|
||||
Node<E> next;
|
||||
public Node(E element, Node<E> next) {
|
||||
this.element = element;
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(element).append("_").append(next.element);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
size = 0;
|
||||
first = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E get(int index) {
|
||||
return node(index).element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E set(int index, E element) {
|
||||
Node<E> node = node(index);
|
||||
E old = node.element;
|
||||
node.element = element;
|
||||
return old;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, E element) {
|
||||
rangeCheckForAdd(index);
|
||||
|
||||
if (index == 0) {
|
||||
Node<E> newFirst = new Node<>(element, first);
|
||||
// 拿到最后一个节点
|
||||
Node<E> last = (size == 0) ? newFirst : node(size - 1);
|
||||
last.next = newFirst;
|
||||
first = newFirst;
|
||||
} else {
|
||||
Node<E> prev = node(index - 1);
|
||||
prev.next = new Node<>(element, prev.next);
|
||||
}
|
||||
size++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E remove(int index) {
|
||||
rangeCheck(index);
|
||||
|
||||
Node<E> node = first;
|
||||
if (index == 0) {
|
||||
if (size == 1) {
|
||||
first = null;
|
||||
} else {
|
||||
Node<E> last = node(size - 1);
|
||||
first = first.next;
|
||||
last.next = first;
|
||||
}
|
||||
} else {
|
||||
Node<E> prev = node(index - 1);
|
||||
node = prev.next;
|
||||
prev.next = node.next;
|
||||
}
|
||||
size--;
|
||||
return node.element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(E element) {
|
||||
if (element == null) {
|
||||
Node<E> node = first;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (node.element == null) return i;
|
||||
|
||||
node = node.next;
|
||||
}
|
||||
} else {
|
||||
Node<E> node = first;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (element.equals(node.element)) return i;
|
||||
|
||||
node = node.next;
|
||||
}
|
||||
}
|
||||
return ELEMENT_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取index位置对应的节点对象
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
private Node<E> node(int index) {
|
||||
rangeCheck(index);
|
||||
|
||||
Node<E> node = first;
|
||||
for (int i = 0; i < index; i++) {
|
||||
node = node.next;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder string = new StringBuilder();
|
||||
string.append("size=").append(size).append(", [");
|
||||
Node<E> node = first;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (i != 0) {
|
||||
string.append(", ");
|
||||
}
|
||||
|
||||
string.append(node);
|
||||
|
||||
node = node.next;
|
||||
}
|
||||
string.append("]");
|
||||
return string.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,144 @@
|
||||
package com.mj.single;
|
||||
|
||||
import com.mj.AbstractList;
|
||||
|
||||
public class SingleLinkedList<E> extends AbstractList<E> {
|
||||
private Node<E> first;
|
||||
|
||||
private static class Node<E> {
|
||||
E element;
|
||||
Node<E> next;
|
||||
public Node(E element, Node<E> next) {
|
||||
this.element = element;
|
||||
this.next = next;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
size = 0;
|
||||
first = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E get(int index) {
|
||||
/*
|
||||
* 最好:O(1)
|
||||
* 最坏:O(n)
|
||||
* 平均:O(n)
|
||||
*/
|
||||
return node(index).element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E set(int index, E element) {
|
||||
/*
|
||||
* 最好:O(1)
|
||||
* 最坏:O(n)
|
||||
* 平均:O(n)
|
||||
*/
|
||||
Node<E> node = node(index);
|
||||
E old = node.element;
|
||||
node.element = element;
|
||||
return old;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, E element) {
|
||||
/*
|
||||
* 最好:O(1)
|
||||
* 最坏:O(n)
|
||||
* 平均:O(n)
|
||||
*/
|
||||
rangeCheckForAdd(index);
|
||||
|
||||
if (index == 0) {
|
||||
first = new Node<>(element, first);
|
||||
} else {
|
||||
Node<E> prev = node(index - 1);
|
||||
prev.next = new Node<>(element, prev.next);
|
||||
}
|
||||
size++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E remove(int index) {
|
||||
/*
|
||||
* 最好:O(1)
|
||||
* 最坏:O(n)
|
||||
* 平均:O(n)
|
||||
*/
|
||||
rangeCheck(index);
|
||||
|
||||
Node<E> node = first;
|
||||
if (index == 0) {
|
||||
first = first.next;
|
||||
} else {
|
||||
Node<E> prev = node(index - 1);
|
||||
node = prev.next;
|
||||
prev.next = node.next;
|
||||
}
|
||||
size--;
|
||||
return node.element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(E element) {
|
||||
if (element == null) {
|
||||
Node<E> node = first;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (node.element == null) return i;
|
||||
|
||||
node = node.next;
|
||||
}
|
||||
} else {
|
||||
Node<E> node = first;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (element.equals(node.element)) return i;
|
||||
|
||||
node = node.next;
|
||||
}
|
||||
}
|
||||
return ELEMENT_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取index位置对应的节点对象
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
private Node<E> node(int index) {
|
||||
rangeCheck(index);
|
||||
|
||||
Node<E> node = first;
|
||||
for (int i = 0; i < index; i++) {
|
||||
node = node.next;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder string = new StringBuilder();
|
||||
string.append("size=").append(size).append(", [");
|
||||
Node<E> node = first;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (i != 0) {
|
||||
string.append(", ");
|
||||
}
|
||||
|
||||
string.append(node.element);
|
||||
|
||||
node = node.next;
|
||||
}
|
||||
string.append("]");
|
||||
|
||||
// Node<E> node1 = first;
|
||||
// while (node1 != null) {
|
||||
//
|
||||
//
|
||||
// node1 = node1.next;
|
||||
// }
|
||||
return string.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,127 @@
|
||||
package com.mj.single;
|
||||
|
||||
import com.mj.AbstractList;
|
||||
|
||||
/**
|
||||
* 增加一个虚拟头结点
|
||||
* @author MJ Lee
|
||||
*
|
||||
* @param <E>
|
||||
*/
|
||||
public class SingleLinkedList2<E> extends AbstractList<E> {
|
||||
private Node<E> first;
|
||||
|
||||
public SingleLinkedList2() {
|
||||
first = new Node<>(null, null);
|
||||
}
|
||||
|
||||
private static class Node<E> {
|
||||
E element;
|
||||
Node<E> next;
|
||||
public Node(E element, Node<E> next) {
|
||||
this.element = element;
|
||||
this.next = next;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
size = 0;
|
||||
first = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E get(int index) {
|
||||
return node(index).element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E set(int index, E element) {
|
||||
Node<E> node = node(index);
|
||||
E old = node.element;
|
||||
node.element = element;
|
||||
return old;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, E element) {
|
||||
rangeCheckForAdd(index);
|
||||
|
||||
Node<E> prev = index == 0 ? first : node(index - 1);
|
||||
prev.next = new Node<>(element, prev.next);
|
||||
|
||||
size++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E remove(int index) {
|
||||
rangeCheck(index);
|
||||
|
||||
Node<E> prev = index == 0 ? first : node(index - 1);
|
||||
Node<E> node = prev.next;
|
||||
prev.next = node.next;
|
||||
|
||||
size--;
|
||||
return node.element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(E element) {
|
||||
if (element == null) {
|
||||
Node<E> node = first;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (node.element == null) return i;
|
||||
|
||||
node = node.next;
|
||||
}
|
||||
} else {
|
||||
Node<E> node = first;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (element.equals(node.element)) return i;
|
||||
|
||||
node = node.next;
|
||||
}
|
||||
}
|
||||
return ELEMENT_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取index位置对应的节点对象
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
private Node<E> node(int index) {
|
||||
rangeCheck(index);
|
||||
|
||||
Node<E> node = first.next;
|
||||
for (int i = 0; i < index; i++) {
|
||||
node = node.next;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder string = new StringBuilder();
|
||||
string.append("size=").append(size).append(", [");
|
||||
Node<E> node = first.next;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (i != 0) {
|
||||
string.append(", ");
|
||||
}
|
||||
|
||||
string.append(node.element);
|
||||
|
||||
node = node.next;
|
||||
}
|
||||
string.append("]");
|
||||
|
||||
// Node<E> node1 = first;
|
||||
// while (node1 != null) {
|
||||
//
|
||||
//
|
||||
// node1 = node1.next;
|
||||
// }
|
||||
return string.toString();
|
||||
}
|
||||
}
|
新增問題並參考
封鎖使用者