【数据结构】模拟实现栈和队列
文章目录
- 栈(Stack)
- 栈的概念
- 栈的常用方法
- 模拟实现栈
- 队列(Queue)
- 队列的概念
- 队列的常用方法
- 队列的模拟实现
- 循环队列模拟实现
栈(Stack)
栈的概念
栈是一种特殊的线性表,只允许在固定的一端进行插入和删除操作,进行数据插入和删除的一端称为栈顶,另一端称为栈底。栈的数据遵循后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做压栈/进栈/入栈,入的数据在栈顶。
出栈:栈的删除操作叫做出栈,出的数据在栈顶。
栈的常用方法
//入栈
public void push(int val)
//将栈顶元素出栈并返回
public int pop()
//获取栈顶元素
public int peek()
//检测栈是否为空
public boolean isEmpty()
模拟实现栈
构造一个空栈
public class MyStack {
private int[] elem;
private int usedSize;//栈的实际元素个数
private static final int DEFAULT_CAPACITY = 10;
//初始化栈的大小为DEFAULT_CAPACITY
public MyStack() {
this.elem = new int[DEFAULT_CAPACITY];
}
}
实现push方法(入栈)
public void push(int val) {
//判断栈是否已满 满就扩容
if (this.elem.length == usedSize) {
this.elem = Arrays.copyOf(this.elem,this.elem.length*2);
}
this.elem[usedSize] = val;
usedSize++;
}
实现pop方法(将栈顶元素出栈并返回)
如果栈为空,返回栈顶元素就会报错,我们可以自定义一个异常用来解决报错问题
public class emptyException extends RuntimeException {
public emptyException() {
}
public emptyException(String message) {
super(message);
}
}
public int pop() {
//如果为空栈就抛出一个异常
if (usedSize==0){
throw new emptyException();
}
int oldVal = this.elem[usedSize-1];
usedSize--;
return oldVal;
}
实现peek方法(获取栈顶元素)
public int peek() {
//如果为空栈就抛出一个异常
if (usedSize==0){
throw new emptyException();
}
return this.elem[usedSize-1];
}
实现isEmpty方法(检测栈是否为空)
public boolean isEmpty() {
//判断栈是否为空 只需要判断栈的实际元素个数是否为0即可
return usedSize==0;
}
队列(Queue)
队列的概念
队列是只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列遵循先进先出FIFO(First in First Out)的原则。在Java里面Queue 是一个接口,底层是通过链表实现的。
入队列:进行插入的一端称为队尾。
出队列:进行删除的一端称为队头。
队列的常用方法
//入队
public void offer(int x)
//出队
public int poll()
//获取队头元素x
public int peek()
//获取队列中有效元素的个数
public int size()
//检测队列是否为空
public boolean isEmpty()
队列的模拟实现
双链表模拟实现队列
public class MyQueue {
static class ListNode {
public int val;
public ListNode next;
public ListNode prev;
public ListNode(int val) {
this.val = val;
}
}
public ListNode front;//队头
public ListNode rear;//队尾
public int usedSize = 0;//队列实际元素个数
}
实现offer方法(入队)
public void offer(int x) {
ListNode node = new ListNode(x);
//队列为空
if (front==null){
front=rear=node;
}else {
node.next=front;
front.prev=node;
front=node;
}
usedSize++;
}
实现poll方法(出队)
public int poll(){
//队列为空
if (front==null){
return -1;
}
int ret = rear.val;
//队列中只有一个元素
if (front==rear){
front=null;
rear=null;
usedSize--;
return ret;
}
//删除尾节点
rear=rear.prev;
rear.next=null;
usedSize--;
}
实现peek方法(获取队头元素)
public int peek(){
if (front==null){
return -1;
}
return front.val;
}
实现size方法(获取队列中有效元素的个数)
public int size(){
return usedSize;
}
实现isEmpty方法(检测队列是否为空)
public boolean isEmpty(){
return front==null;
}
循环队列模拟实现
public class MyCircularQueue {
public int[] elem;
public int front;//队头
public int rear;//队尾
//构造循化队列
public MyCircularQueue(int len) {
this.elem = new int[len+1];
}
//入队
public boolean enQueue(int val){
//判断队列是否装满
if (isFull()){
return false;
}
elem[rear] = val;
rear = (rear+1)%elem.length;
return true;
}
//检测队列是否装满
private boolean isFull() {
return (rear+1)%elem.length==front;
}
//出队
public boolean deQueue(){
if (isFull()){
return false;
}
front = (front+1)%elem.length;
return true;
}
//获取队头元素
public int getFront(){
if (isEmpty()){
return -1;
}
return elem[front];
}
//检测队列是否为空
public boolean isEmpty(){
return front==rear;
}
}