DEMO地址:https://github.com/zhaopingfu/MDataStruct
java中常用的链式表是LinkedList
- 优点:增加,删除元素效率高
- 缺点:查询,修改元素效率低
LinkedList中有一个Node内部类,该类中有两个属性,一个是next,一个是previous,相当于两个指针,有一个占位符root,当查找元素的时候就可以根据root,root.next就是整个链表的第一个元素,root.previous就是整个链表最后一个元素
这里的root元素是不看做链表里的元素的,只是个占位符
单向链表
package com.pf;
/**
* @author zhaopf
* @version 1.0
* @QQ: 1308108803
* @date 2017年11月14日
* 单链表
*/
public class MSinglyLinkedList<T> {
private Node<T> first;
private Node<T> last;
private int size;
public boolean add(T data) {
Node<T> node = new Node<>(null, data);
if (first == null) {
first = node;
last = node;
} else {
last.next = node;
last = node;
}
size++;
return true;
}
public boolean add(int index, T data) {
if (index >= 0 && index <= size) {
if (index == size) {
return add(data);
} else if (index == 0) {
Node<T> node = first;
Node<T> newNode = new Node<>(node, data);
newNode.next = node;
first = newNode;
size++;
return true;
} else {
Node<T> node = elementData(index - 1);
Node<T> newNode = new Node<>(node.next, data);
node.next = newNode;
size++;
return true;
}
}
throw new ArrayIndexOutOfBoundsException("index:" + index + ",size:" + size);
}
public T get(int index) {
checkIndex(index);
return elementData(index).data;
}
public T set(int index, T newData) {
checkIndex(index);
Node<T> node = elementData(index);
T result = node.data;
node.data = newData;
return result;
}
public boolean remove(int index) {
checkIndex(index);
if (index == 0) {
first = first.next;
size--;
if (first == null) {
last = null;
}
return true;
} else if (index == size - 1) {
Node<T> node = elementData(index - 1);
node.next = null;
size--;
last = node;
if (last == null) {
first = null;
}
return true;
} else {
Node<T> node = elementData(index - 1);
node.next = node.next.next;
size--;
return true;
}
}
public boolean remove(T data) {
if (data == null) {
Node<T> node = first;
int i = 0;
while (node != null) {
if (node.data == null) {
return remove(i);
}
node = node.next;
i++;
}
} else {
Node<T> node = first;
int i = 0;
while (node != null) {
if (data.equals(node.data)) {
return remove(i);
}
node = node.next;
i++;
}
}
return false;
}
Node<T> elementData(int index) {
Node<T> temp = first;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
return temp;
}
private void checkIndex(int index) {
if (index < 0 || index >= size) {
throw new ArrayIndexOutOfBoundsException("index:" + index + ",size:" + size);
}
}
public int size() {
return size;
}
private class Node<T> {
private Node<T> next;
private T data;
public Node(Node<T> next, T data) {
this.next = next;
this.data = data;
}
}
}
双向循环链表
个人写了个类似的,实现了增删改查功能
package com.pf;
public class MLinkedList<T> {
private Node<T> root;
private int size;
public MLinkedList() {
root = new Node<T>(null, null, null);
}
public boolean add(T data) {
addLast(data);
return true;
}
public boolean add(int index, T data) {
if (index >= 0 && index <= size) {
if (index == size) {
addLast(data);
} else {
Node<T> node = elementData(index);
addBefore(node, data);
}
return true;
}
throw new ArrayIndexOutOfBoundsException("index is " + index + ", size is " + size);
}
public T get(int index) {
return elementData(index).data;
}
public T set(int index, T newData) {
checkIndex(index);
Node<T> node = elementData(index);
T result = node.data;
node.data = newData;
return result;
}
public boolean remove(int index) {
checkIndex(index);
return delete(index);
}
public boolean remove(T data) {
if (data == null) {
Node<T> temp = root.next;
while (temp != root) {
if (temp.data == null) {
temp.previous.next = temp.next;
temp.next.previous = temp.previous;
temp = null;
size--;
return true;
}
temp = temp.next;
}
} else {
Node<T> temp = root.next;
while (temp != root) {
if (data.equals(temp.data)) {
temp.previous.next = temp.next;
temp.next.previous = temp.previous;
temp = null;
size--;
return true;
}
temp = temp.next;
}
}
return false;
}
private boolean delete(int index) {
Node<T> oldLast = elementData(index);
oldLast.previous.next = oldLast.next;
oldLast.next.previous = oldLast.previous;
oldLast = null;
size--;
return true;
}
private void addBefore(Node<T> oldNode, T data) {
Node<T> preNode = oldNode.previous;
Node<T> newNode = new Node<T>(preNode, data, oldNode);
preNode.next = newNode;
oldNode.previous = newNode;
size++;
}
private void addLast(T data) {
Node<T> oldLast = root.previous;
Node<T> newNode = new Node<T>(oldLast, data, root);
if (oldLast == null) {
root.next = newNode;
root.previous = newNode;
newNode.previous = root;
} else {
oldLast.next = newNode;
root.previous = newNode;
}
size++;
}
Node<T> elementData(int index) {
if (index < (size >> 2)) {
Node<T> temp = root.next;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
return temp;
} else {
Node<T> temp = root.previous;
for (int i = size - 1; i > index; i--) {
temp = temp.previous;
}
return temp;
}
}
private void checkIndex(int index) {
if (index < 0 || index >= size) {
throw new ArrayIndexOutOfBoundsException("index is " + index + ", size is " + size);
}
}
@SuppressWarnings("hiding")
private class Node<T> {
private Node<T> previous;
private Node<T> next;
private T data;
public Node(Node<T> previous, T data, Node<T> next) {
super();
this.previous = previous;
this.next = next;
this.data = data;
}
}
public int size() {
return size;
}
}