栈概念
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则.
压栈 和 出栈
压栈 : 就是栈的插入操作,也叫进栈,入栈,往栈顶放.
出栈 : 栈的删除操作叫做出栈,就是栈顶元素往外出.
实现栈
它可用顺序表实现,也可以用链表实现,顺序表较为简单,我这里用顺序表模拟实现,更容易理解一些
public class MyStack {
public int[] elem; // 模拟栈的数组
public int usedSize; //栈元素
public MyStack(){
this.elem = new int[5]; // 给5个元素的空间
}
public void push(int val){
//模拟进栈
if(isFull()){
//判断栈没有
this.elem = Arrays.copyOf(elem,2 * elem.length); // 如果满了,我们这里给二倍扩容
}
this.elem[usedSize] = val; //数组下标从0开始,我们这里让进栈的元素加到末尾
usedSize++; //进栈元素之后记得让原来的元素加一
}
public boolean isFull(){
//判断栈满没有
return this.usedSize == elem.length;
}
public int pop(){
//模拟出栈操作
if(isEmpty()){
//判断栈元素为不为空
throw new RuntimeException("栈为空!"); //栈为空后,抛一个异常出去,表明栈为空
}
int oldVal = this.elem[usedSize-1]; // 记录栈顶的元素
usedSize--; //直接让元素减一,栈顶元素就消失了
return oldVal; //返回刚刚我们记录的栈顶元素
}
public boolean isEmpty(){
//判断栈元素为不为空
return usedSize == 0;
}
public int peek(){
if(isEmpty()){
//判断栈元素为不为空
throw new RuntimeException("栈为空!"); //栈为空后,抛一个异常出去,表明栈为空
}
return this.elem[usedSize-1];//直接返回栈顶元素
}
}
测试刚刚模拟的栈:
public class TestDemo {
public static void main(String[] args) {
MyStack stack = new MyStack();
stack.push(5);
System.out.println(stack.pop());
stack.push(4);
System.out.println(stack.peek());
stack.push(3);
System.out.println(stack.peek());
stack.push(2);
System.out.println(stack.peek());
stack.push(1);
System.out.println(stack.peek());
}
}
public class TestDemo {
public static void main(String[] args) {
MyStack stack = new MyStack();
stack.push(5);
System.out.println(stack.pop());
stack.push(4);
System.out.println(stack.peek());
stack.push(3);
System.out.println(stack.peek());
stack.push(2);
System.out.println(stack.peek());
stack.push(1);
System.out.println(stack.peek());
stack.pop(); //这儿先出了一个栈顶元素1
System.out.println("出的第二个栈顶元素: "+stack.pop()); //接着这儿又出了一个栈顶元素 并且打印 为2
}
}
队列概念
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(FirstIn First Out)
入队列:进行插入操作的一端称为队尾(Tail/Rear)
出队列:进行删除操作的一端称为队头(Head/Front)
扫描二维码关注公众号,回复:
13853209 查看本文章
普通队列模拟实现
我这里用单链表实现,比较简单易懂:
class Node{
public int val; //节点值
public Node next; //指向下一个节点
public Node(int val){
this.val = val;
}
}
public class MyQueue {
public Node head; //头结点(队头)
public Node last; //尾结点(队尾)
public void offer(int x){
// 模拟入队
if(head == null){
//第一次入队头队尾都为空
head = new Node(x);
last = head;
}else{
//从队尾入队
last.next = new Node(x); //原队尾节点指向新节点
last = last.next; //新节点变为尾结点(队尾)
}
}
public int poll(){
//模拟出队
if(head == null){
//队列为空,返回空
throw new RuntimeException("队列为空");
}else {
Node node = head; //记录头结点(队头)
head = head.next; //原头结点指向下一个节点
return node.val; //返回记录的头结点(队头)
}
}
public int peek() {
//模拟队头元素
if (head == null) {
//队列为空,返回空
throw new RuntimeException("队列为空");
} else {
return head.val; //直接返回队头
}
}
}
测试:
public class TestDemo {
public static void main(String[] args) {
MyQueue queue = new MyQueue();
queue.offer(1);
System.out.println(queue.peek());
queue.offer(2);
System.out.println(queue.peek());
queue.offer(3);
System.out.println(queue.poll());
System.out.println(queue.poll());
}
}