数组实现栈
package com.lzf2.class02;
import java.util.Stack;
/**
* 数组实现栈
*/
public class ArrayImplStack {
private int[] element;
private int size;
public ArrayImplStack(int capacity) {
element = new int[capacity];
size = 0;
}
public void push(int item){
if(size <=element.length){
throw new RuntimeException("栈满了,不要在加了");
}
//加入元素
this.element[size++] = item;
}
public int pop(){
if(size == 0){
throw new RuntimeException("栈空了,不要在拿了");
}
//弹出元素
return element[--size];
}
public int peek(){
if(size == 0){
throw new RuntimeException("栈空了,不要在看了");
}
int peekIndex = size - 1;
return element[peekIndex];
}
public boolean empty(){
return size == 0;
}
}
链表实现栈
package com.lzf2.class02;
/**
* 链表实现栈
*/
public class LinkedImplStack {
//单链表节点
private class Node{
int value;
Node Next;
public Node(int value) {
this.value = value;
}
}
private Node head;
private int size;
public LinkedImplStack() {
this.head = null;
size = 0;
}
public void push(int item){
Node newNode = new Node(item);
newNode.Next = head;
head = newNode;
size++;
}
public int pop(){
if(size == 0){
throw new RuntimeException("栈空了,不要在拿了");
}
int result = head.value;
head = head.Next;
size--;
return result;
}
public int peek(){
if(size == 0){
throw new RuntimeException("栈为空");
}
return head.value;
}
public boolean empty(){
return size == 0;
}
}
数组实现队列
package com.lzf2.class02;
/**
* 数组实现队列
*/
public class ArrayImplQueue {
private int[] element;
private int pushIndex;
private int popIndex;
private int size;
public ArrayImplQueue(int capacity) {
element = new int[capacity];
pushIndex = 0;
popIndex = 0;
size = 0;
}
public void push(int item) {
if (size == element.length) {
throw new RuntimeException("队列满了");
}
element[pushIndex] = item;
pushIndex = indexNext(pushIndex);
size++;
}
public int pop() {
if (size == 0) {
throw new RuntimeException("队列空");
}
int result = element[popIndex];
popIndex = indexNext(popIndex);
size--;
return result;
}
public boolean isEmpty() {
return size == 0;
}
private int indexNext(int index) {
return index == element.length - 1 ? 0 : index + 1;
}
}
链表实现队列
package com.lzf2.class02;
import java.util.LinkedList;
import java.util.PriorityQueue;
/**
* 链表实现队列
*/
public class LinkedImplQueue {
//单链表节点
private class Node {
int value;
Node next;
public Node(int value) {
this.value = value;
}
}
private Node head;
private int size;
private Node last;
public LinkedImplQueue() {
this.head = null;
size = 0;
}
public void push(int item){
Node newNode = new Node(item);
if(head == null){//没有元素的时候
head = newNode;
last = newNode;
size++;
return;
}
last.next = newNode;
size++;
}
public int pop(){
if(size == 0){
throw new RuntimeException("队列空");
}
int result = head.value;
head = head.next;
size--;
return result;
}
public boolean isEmpty(){
return size == 0;
}
}
第一题
问题描述:实现一个特殊的栈。在基本功能的基础上,再实现返回栈中最小元素的功能。pop、push、getMin操作的时间复杂度都是 O(1)。 设计的栈类型可以使用现成的栈结构。
提示:两个栈实现,一个数据栈,一个最小值栈
package com.lzf.class02;
import java.util.Stack;
/**
* 实现一个特殊的栈,在基本功能的基础上,再实现返回栈中最小元素的功能
* pop、push、getMin操作的时间复杂度都是 O(1)。
* 设计的栈类型可以使用现成的栈结构。
*
* 用两个栈实现,一个数据栈,一个最小值栈
* 1)每次放入数据栈的数据newData,都去和最小值栈的栈顶数比较
* newData更小或等于时,就放入最小值栈。反之就不放
* 2)每次拿出数据栈的数据时,都去和最小值的栈顶比较
* 如果相等,就弹出最小值栈的栈顶元素
* 3)getMin则只需要去最小值栈peek就可以
*/
public class GetMinStack {
private Stack<Integer> stackData;//数据栈
private Stack<Integer> stackMin;//最小值栈
public GetMinStack() {
stackData = new Stack<>();
stackMin = new Stack<>();
}
public void push(int newNum) {
if(stackMin.isEmpty()){
//最小值栈为空,直接放进去
stackMin.push(newNum);
}else if(newNum<=this.getMin()){
//newNum比数据栈的栈顶元素小,放入最小值栈
stackMin.push(newNum);
}
this.stackData.push(newNum);
}
public int pop() {
if (this.stackData.isEmpty()) {
throw new RuntimeException("Your stack is empty.");
}
Integer value = stackData.pop();
if(value==getMin()){
stackMin.pop();
}
return value;
}
public int getMin(){
if(this.stackMin.isEmpty()){
throw new RuntimeException("Your stack is empty.");
}
return this.stackMin.peek();
}
}
第二题
问题描述:如何用栈结构实现队列结构
提示:两个栈
package com.lzf.class02;
import java.util.Stack;
/**
* 两个栈实现队列
* 两个原则
* 1.倒数据要倒干净
* 2.数据未拿完,不能倒数据
*/
public class TwoStacksImplementQueue {
public static class TwoStacksQueue {
private Stack<Integer> stackPush;
private Stack<Integer> stackPop;
public TwoStacksQueue() {
stackPush = new Stack();
stackPop = new Stack();
}
// push栈向pop栈倒入数据
private void pushToPop() {
//pop为空才能倒
if(stackPop.isEmpty()){
//倒要倒干净
while (!stackPush.isEmpty()){
stackPop.push(stackPush.pop());
}
}
}
//入队
public void add(int value){
stackPush.push(value);
pushToPop();
}
//出队
public int poll() {
if (stackPop.empty() && stackPush.empty()) {
throw new RuntimeException("Queue is empty!");
}
pushToPop();
return stackPop.pop();
}
public int peek(){
if (stackPop.empty() && stackPush.empty()) {
throw new RuntimeException("Queue is empty!");
}
pushToPop();
return stackPop.peek();
}
}
public static void main(String[] args) {
TwoStacksQueue test = new TwoStacksQueue();
test.add(1);
test.add(2);
test.add(3);
System.out.println(test.peek());
System.out.println(test.poll());
System.out.println(test.peek());
System.out.println(test.poll());
System.out.println(test.peek());
System.out.println(test.poll());
}
}
第三题
问题描述:如何用队列结构实现栈结构
提示:两个队列
package com.lzf.class02;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
/**
* 两个队列实现栈
*
*/
public class TwoQueueImplementStack {
public static class TwoQueueStack<T>{
private Queue<T> queue;
private Queue<T> help;
public TwoQueueStack() {
queue = new LinkedList<>();
help = new LinkedList<>();
}
public void push(T value) {
//offer和add
//向满队列添加数据时,add为抛出异常,offer则会返回false
queue.offer(value);
}
public T poll() {
//留一个数,其余数放到另外一个队列。返回剩下的那个数
while (queue.size()>1){
help.offer(queue.poll());
}
T ans = queue.poll();
Queue<T> temp = queue;
queue = help;
help = temp;
return ans;
}
public T peek() {
while (queue.size()>1){
help.offer(queue.poll());
}
T ans = queue.poll();
help.offer(ans);
Queue<T> tmp = queue;
queue = help;
help = tmp;
return ans;
}
public boolean isEmpty() {
return queue.isEmpty();
}
}
public static void main(String[] args) {
System.out.println("test begin");
TwoQueueStack<Integer> myStack = new TwoQueueStack<>();
Stack<Integer> test = new Stack<>();
int testTime = 1000000;
int max = 1000000;
for (int i = 0; i < testTime; i++) {
if (myStack.isEmpty()) {
if (!test.isEmpty()) {
System.out.println("Oops");
}
int num = (int) (Math.random() * max);
myStack.push(num);
test.push(num);
} else {
if (Math.random() < 0.25) {
int num = (int) (Math.random() * max);
myStack.push(num);
test.push(num);
} else if (Math.random() < 0.5) {
if (!myStack.peek().equals(test.peek())) {
System.out.println("Oops");
}
} else if (Math.random() < 0.75) {
if (!myStack.poll().equals(test.pop())) {
System.out.println("Oops");
}
} else {
if (myStack.isEmpty() != test.isEmpty()) {
System.out.println("Oops");
}
}
}
}
System.out.println("test finish!");
}
}