线性结构——动态数组 队列 栈 链表

动态数组 Array

  • 底层通过静态数组实现 resize方法在add方法中*2,在remove方法中,当size到四分之一时/2,以此实现其均摊时间复杂度为O(1)
  • 何时扩容:当add一个元素刚好使数组满时不扩容,当再add一个元素使得超出数组容量才扩容
public class Array<E> {
	private E[] data;
	private int size;

	@SuppressWarnings("unchecked")
	public Array(int capacity) {
		data = (E[]) new Object[capacity];
		size = 0;
	}

	public Array() {
		this(10);
	}

	public int getSize() {
		return size;
	}

	public boolean isEmpty() {
		return size == 0;
	}

	public int getCapacity() {
		return data.length;
	}

	public void add(int index, E e) {
		if (index < 0 || index > size) {
			throw new IllegalArgumentException("add failed.Index is illegal.");
		}
		if (size == data.length) {
			resize(data.length * 2);
		}
		if (index < size) {
			for (int i = size - 1; i >= index; i--) {
				data[i + 1] = data[i];
			}
		}
		data[index] = e;
		size++;
	}

	public void addFirst(E e) {
		add(0, e);
	}

	public void addLast(E e) {
		add(size, e);
	}

	private void resize(int newCapacity) {
		@SuppressWarnings("unchecked")
		E[] newData = (E[]) new Object[newCapacity];
		for (int i = 0; i < size; i++) {
			newData[i] = data[i];
		}
		data = newData;
	}

	public E get(int index) {
		if (index < 0 || index >= size) {
			throw new IllegalArgumentException("get failed.Index is illegal.");
		}
		return data[index];
	}

	public E getFirst() {
		return get(0);
	}

	public E getLast() {
		return get(size - 1);
	}

	public void set(int index, E e) {
		if (index < 0 || index >= size) {
			throw new IllegalArgumentException("set failed.Index is illegal.");
		}
		data[index] = e;
	}

	public boolean contains(E e) {
		int ret = find(e);
		if (ret != -1) {
			return true;
		}
		return false;
	}

	public int find(E e) {
		for (int i = 0; i < size; i++) {
			if (e.equals(data[i])) {
				return i;
			}
		}
		return -1;
	}

	public E remove(int index) {
		if (index < 0 || index >= size) {
			throw new IllegalArgumentException("remove failed.Index is illegal.");
		}
		E ret = data[index];
		for (int i = index; i < size - 1; i++) {
			data[i] = data[i + 1];
		}
		data[size - 1] = null;
		size--;
		if (size == data.length / 4 && data.length / 2 != 0) {
			resize(data.length / 2);
		}
		return ret;
	}
	
	public E removeFirst() {
		return remove(0);
	}
	
	public E removeLast() {
		return remove(size - 1);
	}

	public String toString() {
		StringBuilder ret = new StringBuilder();
		ret.append(String.format("Array: size = %d, capacity = %d\n", size, data.length));
		ret.append("[");
		for (int i = 0; i < size; i++) {
			ret.append(data[i]);
			if (i != size - 1) {
				ret.append(", ");
			}
		}
		ret.append("]");
		return ret.toString();
	}

}

链表 LinkedList

  • 底层实现也是动态数据结构
  • 设置了虚拟头结点dummyHead
public class LinkedList<E> {
	class Node {
		public E e;
		public Node next;

		public Node(E e, Node node) {
			this.e = e;
			this.next = node;
		}

		public Node(E e) {
			this(e, null);
		}
	}

	private Node dummyHead;
	private int size;

	public LinkedList() {
		dummyHead = new Node(null, null);
		size = 0;
	}

	public int getSize() {
		return size;
	}

	public boolean isEmpty() {
		return size == 0;
	}

	public void add(int index, E e) {
		if (index < 0 || index > size) {
			throw new IllegalArgumentException("Add failed. Index is illegal");
		}
		Node prev = dummyHead;
		for (int i = 0; i < index; i++) {
			prev = prev.next;
		}
		prev.next = new Node(e, prev.next);
		size++;
	}

	public void addFirst(E e) {
		add(0, e);
	}

	public void addLast(E e) {
		add(size, e);
	}

	public E get(int index) {
		if (index < 0 || index >= size) {
			throw new IllegalArgumentException("Get failed. Index is illegal");
		}
		Node cur = dummyHead.next;
		for (int i = 0; i < index; i++) {
			cur = cur.next;
		}
		return cur.e;
	}

	public E getFirst() {
		return get(0);
	}

	public E getLast() {
		return get(size - 1);
	}

	public void set(int index, E e) {
		if (index < 0 || index >= size) {
			throw new IllegalArgumentException("Set failed. Index is illegal");
		}
		Node cur = dummyHead.next;
		for (int i = 0; i < index; i++) {
			cur = cur.next;
		}
		cur.e = e;
	}

	public boolean contains(E e) {
		Node cur = dummyHead;
		for (int i = 0; i < size; i++) {
			cur = cur.next;
			if (cur.e.equals(e)) {
				return true;
			}
		}
		return false;
	}

	public E remove(int index) {
		if (isEmpty()) {
			throw new IllegalArgumentException("Cannot remove from an empty list");
		}
		if (index < 0 || index >= size) {
			throw new IllegalArgumentException("Remove failed. Index is illegal");
		}
		Node prev = dummyHead;
		for (int i = 0; i < index; i++) {
			prev = prev.next;
		}
		Node retNode = prev.next;
		prev.next = retNode.next;
		retNode.next = null;
		size--;
		return retNode.e;
	}

	public E removeFirst() {
		return remove(0);
	}

	public E removeLast() {
		return remove(size - 1);
	}
	
	public String toString() {
		StringBuilder ret = new StringBuilder();
		Node cur = dummyHead;
		for (int i = 0; i < size; i++) {
			cur = cur.next;
			ret.append(cur.e + "-->");
		}
		ret.append("NULL");
		return ret.toString();
	}

}

队列 Queue FIFO

public interface Queue<E> {
	int getSize();
	boolean isEmpty();
	void enqueue(E e);
	E dequeue();
	E getFront();
}
  • 用数组实现Queue

public class ArrayQueue<E> implements Queue<E> {
	private Array<E> array;

	public ArrayQueue(int capacity) {
		array = new Array<>(capacity);
	}

	public ArrayQueue() {
		array = new Array<>();
	}

	public int getSize() {
		return array.getSize();
	}

	public boolean isEmpty() {
		return array.isEmpty();
	}
	
	public int getCapacity() {
		return array.getCapacity();
	}

	public void enqueue(E e) {
		array.addLast(e);
	}

	public E dequeue() {
		return array.removeFirst();
	}

	public E getFront() {
		return array.getFirst();
	}
	
	public String toString() {
		StringBuilder ret = new StringBuilder();
		ret.append("Queue: front [");
		for (int i = 0; i < array.getSize(); i++) {
			ret.append(array.get(i));
			if (i != array.getSize() - 1) {
				ret.append(", ");
			}
		}
		ret.append("] tail");
		return ret.toString();
	}

}
  • 用数组实现LoopQueue

  • 通过头指针front和尾指针tail实现,front指向第一个元素,tail指向最后一个元素的后一个待添加元素
  • 只有当front和tail指向同一个元素时,才表示队列为空,因此需要在初始化队列大小时隐藏地增加一个空元素
public class LoopQueue<E> implements Queue<E> {

   private E[] data;
   private int front, tail;
   private int size;

   @SuppressWarnings("unchecked")
   public LoopQueue(int capacity) {
   	data = (E[]) new Object[capacity + 1];
   	front = tail = 0;
   	size = 0;
   }

   public LoopQueue() {
   	this(10);
   }

   public int getSize() {
   	return size;
   }

   public boolean isEmpty() {
   	return front == tail;
   }

   public int getCapacity() {
   	return data.length - 1;
   }

   public void enqueue(E e) {
   	if ((tail + 1) % data.length == front) {
   		resize(getCapacity() * 2);
   	}
   	data[tail] = e;
   	tail = (tail + 1) % data.length;
   	size++;
   }

   private void resize(int newCapacity) {
   	@SuppressWarnings("unchecked")
   	E[] newData = (E[]) new Object[newCapacity + 1];
   	for (int i = 0; i < size; i++) {
   		newData[i] = data[(i + front) % data.length];
   	}
   	data = newData;
   	front = 0;
   	tail = size;
   }

   public E dequeue() {
   	if (isEmpty()) {
   		throw new IllegalArgumentException("Queue is empty.");
   	}
   	E ret = data[front];
   	data[front] = null;
   	front = (front + 1) % data.length;
   	size --;
   	if (size == getCapacity() / 4 && getCapacity() / 2 != 0) {
   		resize(getCapacity() / 2);
   	}
   	return ret;
   }

   public E getFront() {
   	if (isEmpty()) {
   		throw new IllegalArgumentException("Queue is empty.");
   	}
   	return data[front];
   }
   
   public String toString() {
   	StringBuilder ret = new StringBuilder();
   	ret.append(String.format("LoopQueue: size = %d, capacity = %d\n", size, getCapacity()));
   	ret.append("front [");
   	for (int i = front; i != tail; i = (i + 1) % data.length) {
   		ret.append(data[i]);
   		if (i != (front + size - 1) % data.length) {
   			ret.append(", ");
   		}
   	}
   	ret.append("] tail");
   	return ret.toString();
   }

}
  • 用链表实现Queue

public class LinkedListQueue<E> implements Queue<E> {

   private class Node {
   	public E e;
   	public Node next;

   	public Node(E e, Node next) {
   		this.e = e;
   		this.next = next;
   	}

   	public Node(E e) {
   		this(e, null);
   	}

   	public String toString() {
   		return e.toString();
   	}
   }

   private Node head, tail;
   private int size;

   public LinkedListQueue() {
   	head = null;
   	tail = null;
   	size = 0;
   }

   public int getSize() {
   	return size;
   }

   public boolean isEmpty() {
   	return size == 0;
   }

   public void enqueue(E e) {
   	Node node = new Node(e);
   	if (head == null) {
   		head = tail = node;
   	} else {
   		tail.next = node;
   		tail = node;
   	}
   	size++;
   }

   public E dequeue() {
   	if (isEmpty()) {
   		throw new IllegalArgumentException("Cannot dequeue from an empty queue.");
   	}
   	Node retNode = head;
   	head = retNode.next;
   	retNode.next = null;
   	if (head == null) {
   		tail = null;
   	}
   	size--;
   	return retNode.e;
   }

   public E getFront() {
   	if (isEmpty()) {
   		throw new IllegalArgumentException("Queue is empty.");
   	}
   	return head.e;
   }

   public String toString() {
   	StringBuilder sb = new StringBuilder();
   	sb.append("Queue: front ");
   	Node cur = head;
   	while (cur != null) {
   		sb.append(cur + "-->");
   		cur = cur.next;
   	}
   	sb.append("NULL tail");
   	return sb.toString();
   }

}

栈 Stack LIFO

public interface Stack<E> {
	int getSize();
	boolean isEmpty();
	void push(E e);
	E pop();
	E peek();
}
  • 用数组实现Stack

public class ArrayStack<E> implements Stack<E> {
   private Array<E> array;

   public ArrayStack() {
   	array = new Array<>();
   }

   public ArrayStack(int capacity) {
   	array = new Array<>(capacity);
   }

   public int getSize() {
   	return array.getSize();
   }

   public boolean isEmpty() {
   	return array.isEmpty();
   }

   public void push(E e) {
   	array.addLast(e);
   }

   public E pop() {
   	return array.removeLast();
   }

   public E peek() {
   	return array.getLast();
   }
   
   public String toString() {
   	StringBuilder ret = new StringBuilder();
   	ret.append("Stack: [");
   	for (int i = 0; i < array.getSize(); i++) {
   		ret.append(array.get(i));
   		if (i != array.getSize() - 1) {
   			ret.append(", ");
   		}
   	}
   	ret.append("] top");
   	return ret.toString();
   }
}
  • 用链表实现Stack

public class LinkedListStack<E> implements Stack<E> {
	private LinkedList<E> list;
	
	public LinkedListStack() {
		list = new LinkedList<>();
	}

	public int getSize() {
		return list.getSize();
	}

	public boolean isEmpty() {
		return list.isEmpty();
	}

	public void push(E e) {
		list.addFrist(e);
	}

	public E pop() {
		return list.removeFirst();
	}

	public E peek() {
		return list.getFirst();
	}
	
	public String toString() {
		StringBuilder res = new StringBuilder();
		res.append("Stack: top ");
		res.append(list);
		return res.toString();
	}

} 

时间复杂度比较

  • Array时间复杂度

Array时间复杂度
addO(n)
addFirstO(n)
addLastO(1)
getO(1)
getFirstO(1)
getLastO(1)
setO(1)
containsO(n)
findO(n)
removeO(n)
removeFirstO(n)
removeLastO(1)
resize均摊O(1)
  • LinkedList时间复杂度

LinkedList时间复杂度
addO(n)
addFirstO(1)
addLastO(n)
getO(n)
getFirstO(1)
getLastO(n)
setO(n)
containsO(n)
removeO(n)
removeFirstO(1)
removeLastO(n)
  • ArrayStack时间复杂度

ArrayStack时间复杂度
pushO(1)
popO(1)
peekO(1)
  • LinkedListStack时间复杂度

LinkedListStack时间复杂度
pushO(1)
popO(1)
peekO(1)
  • ArrayQueue时间复杂度

ArrayQueue时间复杂度
enqueueO(1)
dequeueO(n)
getFrontO(1)
  • LoopQueue时间复杂度

LoopQueue时间复杂度
enqueueO(1)
dequeueO(1)
getFrontO(1)
  • LinkedListQueue时间复杂度

LinkedListQueue时间复杂度
enqueueO(1)
dequeueO(1)
getFrontO(1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值