基础知识
- java实现栈基础栈和队列
- 用链表实现栈和队列
java实现栈的三种方式
import java.util.Arrays;
public class MyStack{
private int[] arr;
// size 记录栈中元素个数
private int size;
public MyStack(){
// 调用无参构造方法 默认最大容量12
this(12);
}
public MyStack(int MaxSize){
this.arr = new int[MaxSize];
}
// 入栈
public int push(int value){
if(this.size == arr.length){
// 栈满 ,需要扩容
int[] copyArr;
// 复制arr 数组并扩容一倍
copyArr = Arrays.copyOf(arr,2 * arr.length);
arr = copyArr;
}
//将元素添加到size位置
this.arr[size] = value;
// 元素个数加一
this.size++;
// 返回添加元素
return value;
}
// 出栈
public int pop(){
if(isEmpty()){
//没有元素
//抛出运行时异常,此处也可以自定义异常
throw new RuntimeException("栈中没有元素,不能出栈....");
}
// 获得栈顶元素
int value = this.arr[size - 1];
// size - 1 之后, 下一次插入时会覆盖原数据,利用覆盖替代删除
this.size--;
return value;
}
// 获取栈顶元素
public int peek(){
if(isEmpty()){
//没有元素
//抛出运行时异常,此处也可以自定义异常
throw new RuntimeException("栈中没有元素,不能出栈....");
}
return this.arr[this.size - 1];
}
//获取元素个数
public int getSize(){
return this.size;
}
//判断元素是否为空
public boolean isEmpty(){
return this.size == 0;
}
}
这里是泛型实现
import java.util.Arrays;
public class MyStack<T>{
private T[] arr;
// size 记录栈中元素个数
private int size;
public MyStack(){
// 调用无参构造方法 默认最大容量12
this(12);
}
public MyStack(int MaxSize){
this.arr = (T[]) new Object[MaxSize];
}
// 入栈
public T push(T value){
if(this.size == arr.length){
// 栈满 ,需要扩容
T[] copyArr;
// 复制arr 数组并扩容一倍
copyArr = Arrays.copyOf(arr,2 * arr.length);
arr = copyArr;
}
//将元素添加到size位置
this.arr[size] = value;
// 元素个数加一
this.size++;
// 返回添加元素
return value;
}
// 出栈
public T pop(){
if(isEmpty()){
//没有元素
//抛出运行时异常,此处也可以自定义异常
throw new RuntimeException("栈中没有元素,不能出栈....");
}
// 获得栈顶元素
T value = this.arr[size - 1];
// size - 1 之后, 下一次插入时会覆盖原数据,利用覆盖替代删除
this.size--;
return value;
}
// 获取栈顶元素
public T peek(){
if(isEmpty()){
//没有元素
//抛出运行时异常,此处也可以自定义异常
throw new RuntimeException("栈中没有元素,不能出栈....");
}
return this.arr[this.size - 1];
}
//获取元素个数
public int getSize(){
return this.size;
}
//判断元素是否为空
public boolean isEmpty(){
return this.size == 0;
}
}
测试类
public static void main(String[] args){
Stack<Integer> stack = new Stack<>();
//入栈
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
System.out.println("栈中有效元素个数 : "+ stack.size()); // 输出 4
System.out.println("获取栈顶元素 : "+stack.peek()); // 获取栈顶元素,但是不出栈,栈中元素不变
stack.pop(); // 出栈 元素 4 出栈 ,栈中剩余元素 3,2,1
System.out.println("获取栈顶元素 : " + stack.pop()); // 获取栈顶元素,出栈, 此时栈中剩余 2,1两个元素
System.out.println("栈中有效元素个数 : "+ stack.size()); // 输出 2
System.out.println("stack是否为空 : "+ stack.isEmpty()); // 判断栈中是否为空
}
public class MyQueue {
int[] elements;
public MyQueue() {
elements = new int[0];
}
public void add(int element){
int[] newArr = new int[elements.length+1];
for (int i = 0; i < elements.length; i++) {
newArr[i] = elements[i];
}
newArr[elements.length] = element;
elements = newArr;
}
public int poll(){
if (elements.length == 0){
throw new RuntimeException("queue is Empty");
}
int element = elements[0];
int[] newArr = new int[elements.length - 1];
for (int i = 0; i < elements.length - 1; i++) {
newArr[i] = elements[i+1];
}
elements = newArr;
return element;
}
public boolean isEmpty(){
return elements.length == 0;
}
}
测试类
public class Test {
public static void main(String[] args) {
MyQueue mq = new MyQueue();
mq.add(1);
mq.add(4);
mq.add(5);
mq.add(45);
System.out.println(mq.poll());
System.out.println(mq.poll());
System.out.println(mq.poll());
System.out.println(mq.poll());
System.out.println(mq.isEmpty());
}
}
232用栈实现队列
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
说明:
你 只能 使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
思路:这里用两个栈来模拟队列,一个逐个压入1栈中,在逐个弹出,压入2栈中。出栈的时候,从2栈逐个弹出就可以,当2为空了,就要重新压入1栈中的所有元素,出2栈的时候和入1栈是没有关联的,因为先进先出,肯定是从2栈里出空了之后再重新加入所有的1栈的元素
- 代码
class MyQueue {
Stack<Integer> stackin;//Integer
Stack<Integer> stackout;
public MyQueue() {
stackin= new Stack<>();
stackout = new Stack<>();//括号忘了加
}
public void push(int x) {
stackin.push(x);
}
public int pop() {
change();
return stackout.pop();
}
public int peek() {
change();
return stackout.peek();
}
public boolean empty() {
return stackin.empty()&&stackout.empty();
}
public void change(){
if(!stackout.empty()) return;
while(!stackin.empty()){
stackout.push(stackin.pop());
}
}
}
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue obj = new MyQueue();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.peek();
* boolean param_4 = obj.empty();
*/
225. 用队列实现栈
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack 类:
void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。
注意:
你只能使用队列的基本操作 —— 也就是 push to back、peek/pop from front、size 和 is empty 这些操作。
你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
- 思路
用两个队列来模拟栈,首先想到上一个两个栈的方法,但是仔细一想,由于队列的性质决定,先进先出,两个队列压进去弹出来再压进去没有用,所以还得想别的办法。看完题解的思路,队列1,队列2,临时队列tmp。队列1中元素的顺序始终和栈的出栈顺序保持一致,队列2作为辅助,临时队列tmp用于交换两个队列,具体的实现思路就是,每push一个元素,就把这个元素放在队列2中,然后把队列1中已经按栈的出栈顺序排好的顺序追加到队列2后面,这时就已经逐个的实现了倒序,再交换队列1和队列2,让队列2中始终保持是栈的出栈顺序,后面的pop,top,empty就可以直接对队列1进行判断输出。
class MyStack {
Queue<Integer> queue1;
Queue<Integer> queue2;
public MyStack() {
queue1 = new LinkedList<>();
queue2 = new LinkedList<>();
}
public void push(int x) {
queue2.offer(x);
while(!queue1.isEmpty()){
queue2.offer(queue1.poll());
}
Queue<Integer> tmp;
tmp=queue1;
queue1=queue2;
queue2=tmp;
}
public int pop() {
return queue1.poll();
}
public int top() {
return queue1.peek();
}
public boolean empty() {
return queue1.isEmpty();
}
}
/**
* Your MyStack object will be instantiated and called as such:
* MyStack obj = new MyStack();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.top();
* boolean param_4 = obj.empty();
*/