常见的数据结构(栈/对列)
一、栈(Stack) 一种具有后进先出(LIFO)特性的数据结构,常用于处理函数调用、表达式求值等。
-
java虚拟机栈
-
就像生活中的 弹夹(装子 ** 弹)
如何创建一个类实现栈的功能?
- 底层存元素使用数组
- 添加元素始终添加到数组的最后一个
- 获取元素时永远从最后一个开始取元素
- 扩容问题
public abstract class Stack {
/**
* 将元素压入栈顶
* 入栈
* @param element 要压入的元素
*/
abstract void push(Object element);
/**
* 弹出栈顶元素并返回
* 把栈顶元素删除,并返回
* 出栈
* @return 弹出的栈顶元素, 如果栈为空返回 null
*/
abstract Object pop();
/**
* 返回栈顶元素,但不弹出
* @return 栈顶元素
*/
abstract Object peek();
/**
* 检查栈是否为空
* @return 如果栈为空则返回true,否则返回false
*/
abstract boolean isEmpty();
/**
* 返回栈中的元素个数
* @return 栈中元素的个数
*/
abstract int size();
}
示例:
import java.util.Arrays;
public class Mystack extends Stack{
private Object[] value;
/*
元素的个数
下一个元素的下标
*/
private int length;
/*
给数组设置一个默认容量
*/
private static final int DEFAULT_CAPACITY = 10;
public Mystack(){
this(DEFAULT_CAPACITY);
}
public Mystack(int capacity) {
if(capacity < 0){
capacity = DEFAULT_CAPACITY;
}
value = new Object[capacity];
}
/**
* 将元素压入栈顶
* 入栈
* @param element 要压入的元素
*/
@Override
void push(Object element) {
if(length + 1 > value.length){
grow();
}
value[length] = element;
length ++;
}
//扩容
private void grow() {
int oldcapacity = value.length;
int newcapacity = oldcapacity <<1;
//判断新的容量是否比旧容量大
if(newcapacity < oldcapacity){
newcapacity = Integer.MAX_VALUE;
}
value = Arrays.copyOf(value ,newcapacity);
}
/**
* 弹出栈顶元素并返回
* 把栈顶元素删除,并返回
* 出栈
* @return 弹出的栈顶元素, 如果栈为空返回 null
*/
@Override
Object pop() {
Object first = value[length -1];
value[length-1] = null;
length --;
return first;
}
/**
* 返回栈顶元素,但不弹出
* @return 栈顶元素
*/
@Override
Object peek() {
return value[length-1];
}
/**
* 检查栈是否为空
* @return 如果栈为空则返回true,否则返回false
*/
@Override
boolean isEmpty() {
return value.length == 0;
}
/**
* 返回栈中的元素个数
* @return 栈中元素的个数
*/
@Override
int size() {
return length;
}
//重写tostring方法
@Override
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0; i < length - 1; i++) {
sb.append(value[i] + ", ");
}
sb.append(value[length - 1]).append("]");
return sb.toString();
}
}
二、队列(Queue):一种具有先进先出(FIFO)特性的数据结构,常用于任务调度、广度优先搜索等。
- 像生活中安检机
如何实现?
- 使用数组存元素
- 存元素还是放到数组的最后
- 取元素从第一个开始取
public abstract class Queue {
/**
* 将元素插入队尾
* @param element 要插入的元素
*/
void enqueue(Object element);
/**
* 移除并返回队首元素
* 删除第一个元素,并返回
* @return 队首元素, 如果队列为空时,返回 null
*/
abstract Object dequeue();
/**
* 返回队首元素,但不移除
* @return 队首元素
*/
abstract Object peek();
/**
* 检查队列是否为空
* @return 如果队列为空则返回true,否则返回false
*/
abstract boolean isEmpty();
/**
* 返回队列中的元素个数
* @return 队列中元素的个数
*/
abstract int size();
}
示例:
import java.util.Arrays;
public class MyQueue extends Queue{
private Object[] value;
private int size;
private static final int DEFAULT_CAPACITY = 10;
public MyQueue(){
this(DEFAULT_CAPACITY);
}
public MyQueue(int capacity) {
if(capacity < 0){
capacity = DEFAULT_CAPACITY;
}
value = new Object[capacity];
}
@Override
void push(Object element) {
if(size + 1 > value.length ){
grow();
}
value[size ++] = element;
}
private void grow(){
int old = value.length;
int newcapacity = old +10;
if(newcapacity <= old){
newcapacity = Integer.MAX_VALUE;
}
value = Arrays.copyOf(value,newcapacity);
}
@Override
Object pop() {
Object fist = value[0];
System.arraycopy(value,1,value,0,size-1);
value[size--] = null;
return fist;
}
@Override
Object peek() {
return value[0];
}
@Override
boolean isEmpty() {
return size == 0;
}
@Override
int size() {
return size;
}
}