2020年6月30日 用两个栈实现队列 CQueue
默认格式:
class CQueue {
public CQueue() {
}
public void appendTail(int value) {
}
public int deleteHead() {
}
}
/**
* Your CQueue object will be instantiated and called as such:
* CQueue obj = new CQueue();
* obj.appendTail(value);
* int param_2 = obj.deleteHead();
*/
解题思路:
首先,我们要用两个栈,栈就是先入后出。然后我们要做成一个队列,队列是先入先出,那要怎么把两个先入后出的结构变成先入先出的结构呢?
先写一个栈的数据结构。
class Node{
Node son;
int val;
Node(int num){
this.val=num;
}
}
class Stack{
Node head;
void push(int val){
Node node= new Node(val);
if (head==null){
head=node;
return;
}
node.son=head;
head=node;
}
int pop(){
if (head==null)
return -1;
int val=head.val;
head=head.son;
return val;
}
}
方式1
插入之前先将栈中所有元素出栈到另一个栈中,然后直接插在栈底,并且把另一个栈中的元素移回来
第一步,栈1依次出栈到栈2中
4如栈1
栈2出栈回到栈1
这么做有一个很大的问题,操作一个数字需要操作整个栈两次,很浪费时间。
优化:
用一个栈专门负责入栈,一个栈专门负责出栈。
这样在连续的入栈的操作时,可以不用操作另一个栈,出栈也是同理。
这样做的话,有一个栈会一直是空的。
出栈:2和3
然后连续入栈5、6
先把3,4换过去
直到出栈操作之前,不需要取出栈
代码实现:
package month6;
import org.junit.Test;
public class CQueue {
Stack stack1;
Stack stack2;
public CQueue() {
stack1=new Stack();
stack2=new Stack();
}
public void appendTail(int value) {
//如果栈1为空,说明当前是入栈操作
if (stack1.head==null){
stack2.push(value);
}
//否则,把栈1的都移动出到栈2中
else
{
while (stack1.head!=null){
stack2.push(stack1.pop());
}
stack2.push(value);
}
}
public int deleteHead() {
if (stack2.head==null){
return stack1.pop();
}
else
{
while (stack2.head!=null){
stack1.push(stack2.pop());
}
return stack1.pop();
}
}
}
class Node{
Node son;
int val;
Node(int num){
this.val=num;
}
}
class Stack{
Node head;
void push(int val){
Node node= new Node(val);
if (head==null){
head=node;
return;
}
node.son=head;
head=node;
}
int pop(){
if (head==null)
return -1;
int val=head.val;
head=head.son;
return val;
}
}
最终优化:
看了官方的解答,发现自己还有一些没想到的点,实际上插入并不需要将栈2中的元素都取出,可以暂时先存在栈1中,这样取的时候也不需要将栈1的元素移动回去,直到栈2空了,在将栈1的元素给移过来
class CQueue {
//stack1负责出栈
Stack stack1;
//stack2负责入栈
Stack stack2;
public CQueue() {
stack1=new Stack();
stack2=new Stack();
}
public void appendTail(int value) {
stack2.push(value);
}
public int deleteHead() {
if (stack1.head==null){
while (stack2.head!=null){
stack1.push(stack2.pop());
}
return stack1.pop();
}
else
{
return stack1.pop();
}
}
class Node{
Node son;
int val;
Node(int num){
this.val=num;
}
}
class Stack{
Node head;
void push(int val){
Node node= new Node(val);
if (head==null){
head=node;
return;
}
node.son=head;
head=node;
}
int pop(){
if (head==null)
return -1;
int val=head.val;
head=head.son;
return val;
}
}
}