線性表的存儲分爲:順序存儲和鏈式存儲
順序存儲的一種實現:ArrayList,數據量大的情況下,查找的效率高,刪除和新增的效率低
鏈式存儲的實現:LinkedList,數據量大的情況下,查找的效率低,刪除和新增的效率低
下面給出簡單的實現:
ArrayList:
package ds.list;
/**
* @author : cuantianhou 2019/12/19
*/
public class MockArrayList<T extends Comparable<T>> {
private Object[] elements;
private int size;
private static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
private int capacity;
private static final int MAX_CAPACITY = 1 << 30;
/**
* 無參構造函數
*/
public MockArrayList(){
elements = new Object[DEFAULT_INITIAL_CAPACITY];
capacity = DEFAULT_INITIAL_CAPACITY;
size = 0;
}
/**
* 有參構造函數
* @param initialCapacity
*/
public MockArrayList(int initialCapacity){
elements = new Object[initialCapacity];
capacity = initialCapacity;
size = 0;
}
/**
* 添加元素
* @param e
*/
public void add(T e){
ensureNewCapacity(size+1);
elements[size++] = e;
}
/**
* 指定位置添加元素
* @param index
* @param e
*/
public void add(int index,T e){
if (index < 0 || index > size){
throw new IndexOutOfBoundsException(index+"");
}
ensureNewCapacity(size+1);
System.arraycopy(elements,index,elements,index+1,size - index);
elements[index] = e;
size++;
}
/**
* 添加列表
* @param arrayList
*/
public void addAll(MockArrayList arrayList){
if (arrayList == null) {
return;
}
addAll(arrayList.elements);
}
public void addAll(Object[] arrayList){
if (arrayList == null)
return;
int len = arrayList.length;
ensureNewCapacity(size+len);
System.arraycopy(arrayList,0,elements,size,len);
size += len;
}
/**
* 自動擴容,每次擴容都擴大到原來的1.5倍
* @param newCapacity
*/
private void ensureNewCapacity(int newCapacity){
if (size <= 0) return;
if (newCapacity > MAX_CAPACITY){
System.out.println("數組大小已達到最大值,無法再插入數據");
return;
}
if (newCapacity <= capacity)
return;
int nc = capacity + capacity >> 1;
if (nc < newCapacity)
nc = newCapacity;
Object[] ne = new Object[nc];
System.arraycopy(elements,0,ne,0,size);
capacity = nc;
elements = ne;
}
/**
* 獲取列表大小
* @return
*/
public int size(){
return size;
}
}
上述代碼的精髓就是: System.arraycopy(elements,0,ne,0,size);
LinkedList:基於雙鏈表實現的
package ds.list;
/**
* @author : cuantianhou 2019/12/19
*/
public class MockLinkedList<T extends Comparable<T> >{
Node<T> head;
Node<T> tail;
int capacity ;
public MockLinkedList(){
capacity = 0;
}
/**
* 頭插法
*/
private void linkHead(T data){
Node node = new Node(data,null,head);
if(head == null){
tail = node;
}else{
head.pre = node;
}
head = node;
}
/**
* 尾插法
*/
private void linkTail(T data){
Node node = new Node(data,tail,null);
if(tail == null){
head = node;
}else{
tail.next = node;
}
tail = node;
}
/**
* 刪除頭部
*/
private void unLinkHead(){
Node next = head.next;
Node temp = head;
head = next;
temp.next = null;
head.pre = null;
}
/**
* 刪除尾部
*/
public void unLinkTail(){
Node pre = tail.pre;
Node temp = tail;
tail = pre;
temp.pre = null;
tail.next = null;
}
/**
* 刪除節點信息
*/
public boolean unLink(Node node){
if(node == null) {
return false;
}
if(node == head){
unLinkHead();
capacity--;
return true;
}
if(node == tail){
unLinkTail();
capacity--;
return true;
}
Node pre = node.pre;
Node next = node.next;
pre.next = next;
next.pre = pre;
node.pre = null;
node.next = null;
capacity--;
return true;
}
/**
* 獲取節點信息 索引
*/
private Node getNode(int index){
if(index < 0 || index > capacity){
throw new IndexOutOfBoundsException("IndexOutOfBoundsException");
}
int mid = (capacity-1)>>1;
Node resultNode;
/**
* 遍歷後面的數據
*/
if(index >= mid) {
resultNode = tail;
for (int i = capacity - 1; i > index; i--) {
resultNode = resultNode.pre;
}
return resultNode;
}
/**
* 遍歷前面的數據
*/
resultNode = head;
for (int i = 0; i < index; i++) {
resultNode = resultNode.next;
}
return resultNode;
}
/**
* 獲取節點 元素
* @param data
* @return
*/
private Node getNode(T data){
Node node = head;
while(node != null){
if(node.data.compareTo(data) == 0){
return node;
}
node = node.next;
}
return null;
}
/**
* 判斷是否包含某一個元素
* @param data
* @return
*/
public boolean contains(T data){
return getNode(data) == null? Boolean.FALSE : Boolean.TRUE;
}
/**
* 獲取頭結點
* @return
*/
public Node getHead(){
return head;
}
/**
* 獲取尾結點
* @return
*/
public Node getTail(){
return tail;
}
/**
* 刪除元素
* @param e
* @return
*/
public T remove(T e){
Node<T> node = getNode(e);
return unLink(node) ? node.data:null;
}
/**
* 尾插法
* @param e
* @return
*/
public boolean addTail( T e){
linkTail(e);
capacity++;
return true;
}
/**
* 頭插法
* @param e
* @return
*/
public boolean addHead(T e){
linkHead(e);
capacity++;
return true;
}
/**
* 插入方法
* @param e 元素
* @return
*/
public boolean add(T e){
return addTail(e);
}
/**
*
* 重寫ToString方法
*/
@Override
public String toString(){
if(head == null){
return "[]";
}
StringBuilder stringBuilder = new StringBuilder("[");
Node node = head;
while(node != null){
stringBuilder.append(node.data).append(", ");
node = node.next;
}
return stringBuilder.substring(0,stringBuilder.length()-2)+"]";
}
/**
* 節點信息
*/
private final static class Node<T extends Comparable<T>>{
/**
* 數據
*/
T data;
/**
* 前驅
*/
Node pre;
/**
* 後繼
*/
Node next;
/**
* 構造函數
* @param data 數據
* @param pre 前驅
* @param next 後繼
*/
public Node(T data,Node pre, Node next){
this.data = data;
this.pre = pre;
this.next = next;
}
}
}