1.Stack
Stack 栈是一个 "先进后出"的原理
实现代码:
public class Stack {
private int capacity=10;
private int[]data;
private int top=-1;
public Stack() {
data=new int[capacity];
}
public Stack(int capacity) {
this.capacity=capacity;
}
public void push(int e) {
top++;
data[top]=e;
}
public int pop() {
int value=data[top];
top--;
return value;
}
public int peek() {
return data[top];
}
public boolean isEmpty() {
if(top==-1)
return true;
return false;
}
public void clear() {
data=null;
top=-1;
}
public int size() {
return top+1;
}
public String toString() {
String s="";
for(int i=top;i>=0;i--) {
s+=data[i]+" ";
}
return s;
}
}
测试操作:
public static void main(String[] args) {
Stack s=new Stack();
System.out.println(s.isEmpty());
s.push(1);
s.push(2);
s.push(3);
System.out.println(s.toString());
System.out.println(s.peek());
System.out.println(s.pop());
System.out.println(s.toString());
System.out.println(s.isEmpty());
}
运行结果:
true
3 2 1
3
3
2 1
false
2.Queue
队列 Queue :先进先出
我们需要两个栈来模仿队列:分别为入栈和出栈
当我们需要进行入栈操作时,需要判断StackB栈是否为空 若为空直接将元素加入StackA栈里,若不为空则应当将StackB栈元素加入StackA栈,再进行入栈操作。
当我们需要进行出栈操作时,需要判断StackA栈是否为空 若为空直接将元素从StackB出栈,若不为空则应当将StackA栈元素加入StackB栈,再进行出栈操作。
实现代码
class Queue {
private Stack stackA;
private Stack stackB;
public Queue() {
stackA=new Stack();
stackB=new Stack();
}
public void offer(int e) {
stackA.push(e);
}
public int poll() {
while(!stackA.isEmpty()) {
stackB.push(stackA.pop());
}
return stackB.pop();
}
public int element() {
while(!stackA.isEmpty()) {
stackB.push(stackA.pop());
}
int temp=stackB.peek();
while(!stackB.isEmpty()) {
stackA.push(stackB.pop());
}
return temp;
}
public int size() {
return stackA.size()+stackB.size();
}
public boolean isEmpty() {
return stackA.size()==0&&stackB.size()==0;
}
public void clear() {
stackA.clear();
stackB.clear();
}
public String toString() {
return stackA.toString();
}
public boolean equals(Object o) {
return this.toString()==o.toString();
}
}
测试操作:
public static void main(String[] args) {
Queue q=new Queue();
System.out.println(q.size());
System.out.println(q.isEmpty());
q.offer(1);
q.offer(2);
q.offer(3);
q.offer(4);
System.out.println(q.element());
System.out.println(q.size());
q.poll();
System.out.println(q.element());
System.out.println(q.toString());
System.out.println(q.isEmpty());
q.clear();
System.out.println(q.isEmpty());
}
运行结果:
0
true
1
4
2
4 3 2
false
true
3.ArrayList
我们在使用数组的时候,经常困惑的一点是怎样设置数组的大小:因为数组元素的个数可能是未知的,如果我们设置的容量太小,那么我们在添加元素的时候,不得不考虑扩容问题;如果设置的容量太大,又有可能造成空间浪费。而ArrayList的优势就在于此:我们可以在添加和去除数组元素的时候,不用去担心数组的大小设置带来的上述问题。
实现代码:
public class ArrayList {
private Object[] objs;
private int size;
private int capacity;
public ArrayList() {
this.capacity = 10;
this.objs = new Object[this.capacity];
}
public ArrayList(int capacity) {
this.capacity = capacity;
this.objs = new Object[this.capacity];
}
public void add(Object obj) {
if (this.isFull()) {
this.grow();
}
this.objs[size++] = obj;
}
private void grow() {
int newCapaCity = this.capacity + (this.capacity >>> 1);
System.out.println("扩容开始,容量由"+ this.capacity +"变为:"+ newCapaCity);
this.objs = Arrays.copyOf(this.objs, newCapaCity);
this.capacity = newCapaCity;
System.out.println("扩容成功");
}
private boolean isFull() {
return this.size == this.capacity;
}
public void add(int index, Object obj) {
if (this.isFull()) {
this.grow();
}
for (int i = size; i > index ; i--) {
this.objs[i] = this.objs[i - 1];
}
this.objs[index] = obj;
this.size++;
}
public void remove(int index) {
for (int i = index; i < this.size; i++) {
this.objs[i] = this.objs[i+1];
}
this.size--;
}
public boolean remove(Object obj) {
if (obj==null){
for (int i=0;i<size;i++){
if (objs[i]==obj){
remove(i);
return true;
}
}
}else {
for (int i=0;i<size;i++){
if (obj.equals(objs[i])){
remove(i);
return true;
}
}
}
return false;
}
public void update(int index, Object obj) {
this.objs[index] = obj;
}
public Object load(Object Object) {
return null;
}
public Object get(int index) {
if (index < size) {
return null;
}
return this.objs[index];
}
public Object[] list() {
return Arrays.copyOf(this.objs, size);
}
public void clear() {
this.size = 0;
}
@Override
public String toString() {
return "ArrayList [objs=" + Arrays.toString(objs) + ", size=" + size + ", capacity=" + capacity + "]";
}
public int size() {
return this.size;
}
}
测试操作:
public static void main(String[] args) {
ArrayList l=new ArrayList();
System.out.println(l.isFull());
l.add(1);
l.add("a");
l.add(2);
l.add(3);
l.add("b");
l.add(4);
System.out.println(l.toString());
l.remove(1);
l.remove(Integer.valueOf(2));
System.out.println(l.toString());
}
运行结果:
false
ArrayList [objs=[1, a, 2, 3, b, 4, null, null, null, null], size=6, capacity=10]
ArrayList [objs=[1, 3, b, 4, null, null, null, null, null, null], size=4, capacity=10]
4.LinkedList
链表是一种物理存储结构上不连续的存储结构,是由存储元素的结点连接而成。每一个节点都包含前一个节点的引用,后一个节点的引用和节点存储的值。
这里实现双向链表
自定义链表的每一个节点所对应的数据结构
class Node {
Node prev;
Node next;
Object value;
public Node() {
}
public Node(Node prev, Object value, Node next) {
this.prev = prev;
this.next = next;
this.value = value;
}
}
实现代码:
public class LinkedList {
private Node first;
private Node last;
private int size;
public LinkedList() {
}
public void add(Object obj) {
// 向尾部添加一个新的节点
Node newNode = new Node();
newNode.value = obj;
// 判断是否是第一次添加
if (first == null) {
this.first = newNode;
this.last = newNode;
} else {
newNode.prev = last;
last.next = newNode;
last = newNode;
}
this.size++;
}
//在指定位置处添加元素
public void add(int index, Object obj) {
if (index < 0 || index > size) {
throw new IllegalArgumentException();
}
if (index == size - 1) {
add(obj);
} else {
Node indexNode = getNode(index);
Node preNode = indexNode.prev;
Node node = new Node(preNode, obj, indexNode);
if (preNode == null) {
first = node;
} else {
preNode.next = node;
indexNode.prev = node;
}
size++;
}
}
//获取第index位置处的节点
public Node getNode(int index) {
if (index < 0 || index > size) {
throw new IllegalArgumentException();
}
Node temp = first;
for (int i = 0; i <= index; i++) {
if (i == index) {
return temp;
}
temp = temp.next;
}
return null;
}
//获取第index位置处的节点的值
public Object get(int index) {
if (index >= this.size || index < 0) {
throw new RuntimeException("对不起,不存在这个下标");
}
Node temp = first;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
return temp.value;
}
boolean contains(String str) {
Node temp = first;
for (int i = 0; i < size; i++) {
if (temp.value.equals(str)) {
return true;
}
temp = temp.next;
}
return false;
}
public String toString() {
StringBuffer sb = new StringBuffer("[");
Node temp = first;
if(temp != null) {
while (temp != null) {
sb.append(temp.value).append(", ");
temp = temp.next;
}
return sb.substring(0, sb.length() - 2)+"]";
}
return "";
}
public Object remove(int index) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException();
}
Node node = getNode(index);
Object res = node.value;
Node preNode = node.prev;
Node nextNode = node.next;
if (preNode == null) {
nextNode.prev = null;
first = nextNode;
} else if (nextNode == null) {
preNode.next = null;
last = preNode;
} else {
preNode.next = nextNode;
nextNode.prev = preNode;
}
size--;
return res;
}
boolean remove(Object item) {
Node temp = first;
for (int i = 0; i < size; i++) {
if (temp.value.equals(item)) {
remove(i);
}
temp = temp.next;
}
return false;
}
void clear() {
Node temp = first;
while (temp != null) {
Node t = temp.next;
temp.prev = null;
temp.value = null;
temp.next = null;
temp = t;
}
first = null;
last = null;
size = 0;
}
}
测试代码:
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
linkedList.add("aa");
linkedList.add("cc");
linkedList.add("bb");
linkedList.add("cc");
linkedList.add("dd");
System.out.println(linkedList);
linkedList.remove("cc");
System.out.println(linkedList);
linkedList.add(2, 1);
System.out.println(linkedList);
linkedList.clear();
System.out.println(linkedList.size);
}
运行结果:
[aa, cc, bb, cc, dd]
[aa, bb, cc, dd]
[aa, bb, 1, cc, dd]
0