1、单向链表设计
LinkedList
package com.company;
public class LinkedList<E> extends AbstractList<E> {
private Node<E> first;
@Override
public void clear() {
size = 0;
first = null;
}
@Override
public E get(int index) {
return (E) node(index);
}
@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) {
if (index == 0) {
first = new Node<>(element, first);
} else {
Node<E> preViousNode = node(index - 1);
preViousNode.next = new Node<>(element, preViousNode.next);
}
size++;
}
@Override
public E remove(int index) {
Node<E> node = first;
if (index == 0) {
first = first.next;
} else {
Node<E> preNode = node(index - 1);
node = preNode.next;
preNode.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;
}
@Override
public void ensureCapacity(int capacity) {
}
private static class Node<E> {
E element;
Node<E> next;
public Node(E element, Node<E> next) {
this.element = element;
this.next = next;
}
}
/**
* 根据索引,获取node
* @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("]");
return string.toString();
}
}
AbstractList
package com.company;
public abstract class AbstractList<E> implements List<E> {
protected int size;
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public boolean contains(E element) {
return indexOf(element) != ELEMENT_NOT_FOUND;
}
public void add(E element) {
add(size, element);
}
protected void outOfBounds(int index) {
throw new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
}
@Override
public void rangeCheck(int index) {
if (index < 0 || index >= size) {
outOfBounds(index);
}
}
protected void rangeCheckForAdd(int index) {
if (index < 0 || index > size) {
outOfBounds(index);
}
}
}
List
package com.company;
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);
/**
* 返回某个元素的索引
* @param index
* @return
*/
E get(int index);
/**
* 设置位置的元素
* @param index
* @param element
* @return 原来的元素
*/
E set(int index, E element);
/**
* 在某个位置插入元素
* @param index
* @param element
*/
void add(int index, E element);
/**
* 删除某个元素
* @param index
* @return
*/
E remove(int index);
/**
* 查看元素的索引
* @param element
* @return
*/
int indexOf(E element);
@Override
String toString();
void rangeCheck(int index);
/**
* 保证容量
* @param capacity
*/
void ensureCapacity(int capacity);
}
2、单向循环链表
package com.jh.circle;
import com.jh.AbstractList;
public class circleLinkedList<E> extends AbstractList<E> {
private Node<E> first;
private Node<E> currentNode;
private static class Node<E> {
E element;
Node<E> next;
public Node(E element, Node<E> next) {
this.element = element;
this.next = next;
}
}
/**
* 根据索引,获取node
* @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;
}
public void reset() {
currentNode = first;
}
public E next() {
if (currentNode == null) {
return null;
}
currentNode = currentNode.next;
return currentNode.element;
}
public E remove() {
if (currentNode == null) {
return null;
}
return remove(currentNode);
}
private E remove(Node<E> node) {
E oldE = node.element;
if (size == 1) {
// 这个顺序不能调换,先拿最后一个,再变更first才能保证准确性
Node<E> lastNode = node(size - 1);
first = first.next;
lastNode.next = first;
} else {
Node<E> nextNode = node.next;
E elementE = nextNode.element;
node.element = elementE;
node.next = nextNode.next;
}
size--;
return oldE;
}
@Override
public void clear() {
size = 0;
first = null;
}
@Override
public E get(int index) {
return (E) node(index);
}
@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> lastNode = (size == 0) ? newFirst : node(size - 1);
lastNode.next = newFirst;
first = newFirst;
} else {
Node<E> preViousNode = node(index - 1);
preViousNode.next = new Node<>(element, preViousNode.next);
}
size++;
}
@Override
public E remove(int index) {
rangeCheck(index);
Node<E> node = first;
if (index == 0) {
// 这个顺序不能调换,先拿最后一个,再变更first才能保证准确性
Node<E> lastNode = node(size - 1);
first = first.next;
lastNode.next = first;
} else {
Node<E> preNode = node(index - 1);
node = preNode.next;
preNode.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;
}
@Override
public void ensureCapacity(int capacity) {
}
// @Override
// public void rangeCheck(int index, boolean isForAdd) {
// // TODO Auto-generated method stub
//
// }
@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(",");
}
if (node != null) {
string.append(node.element);
node = node.next;
}
}
string.append("]");
return string.toString();
}
}
3、约瑟夫问题
static void Joself() {
circleLinkedList<Integer> list = new circleLinkedList<>();
for (int i = 1; i <= 8; i++) {
list.add(i);
System.out.println(list);
}
//
list.reset();
while (!list.isEmpty()) {
list.next();
list.next();
System.out.println(list.remove());
System.out.println(list);
}
}
public static void main(String[] args) {
Joself();
}
算法可视化网站: