数据结构二堆栈变队列,二队列变堆栈

来源:互联网 发布:淘宝最新版本下载2016 编辑:程序博客网 时间:2024/06/18 17:44
初看此题目,你可能觉得自找苦吃,队列就队列为什么要用栈来实现,工程中总是很典型的应用,直接调API就可以了,不管是什么语言,已经有现成API封装好队列以及堆栈的所有操作。没错,在项目中很少有这样的需要。但是我们是站在学习的角度,并不是画地为牢,难为自己,而是对思维的一种锻炼,对算法的提升么。我们在面试的时候碰到的这类问题还少吗?所以大家就不要拍砖了。现在开始研究此问题。

首先看如何用两个栈去实现一个队列,栈所具有的操作主要是push和pop。也就是面对一个桶,只能在顶上拿元素或放元素,别的地方都是封闭的。而一个队列所具有的特性是offer(尾部入队)和poll(队首出队)。相当于一个两端开口的桶,一端只能放,一端只能取。

而如何将一个只有一端操作的变成两端操作的呢,其实就是用两个一端操作的。就可以完成一个两端操作的。用栈1来专门处理offer(入队操作,在队尾),用栈2来处理poll(出队操作,在队首)。那么栈1和栈2的数据需要完全相反,那么队列两端就完全暴露出来了。自己画个图出来就更明显了。代码如下:
[java] view plaincopy
  1. import java.util.Stack;  
  2.   
  3. public class MyQueue {  
  4.     private Stack<String> stackFirst = new Stack<String>();  
  5.     private Stack<String> stackSecond = new Stack<String>();  
  6.       
  7.     public boolean offer(String str){  
  8.         if(stackSecond.empty()){  
  9.             stackFirst.push(str);  
  10.         }else{  
  11.             while(!stackSecond.empty()){  
  12.                 stackFirst.push(stackSecond.pop());  
  13.             }  
  14.             stackFirst.push(str);  
  15.         }  
  16.         return true;  
  17.     }  
  18.       
  19.     public String poll(){  
  20.         if(!stackSecond.empty()){  
  21.             return stackSecond.pop();  
  22.         }else{  
  23.             while(!stackFirst.empty()){  
  24.                 stackSecond.push(stackFirst.pop());  
  25.             }  
  26.             return stackSecond.pop();  
  27.         }  
  28.     }  
  29.       
  30.     public boolean empty(){  
  31.         if(stackFirst.empty() && stackSecond.empty())  
  32.             return true;  
  33.         return false;  
  34.     }  
  35.       
  36.     public static void main(String[] args){  
  37.         MyQueue queue = new MyQueue();  
  38.         queue.offer("hello ");  
  39.         queue.offer("baby ");  
  40.         queue.offer("!");  
  41.           
  42.         while(!queue.empty()){  
  43.             System.out.print(queue.poll());  
  44.         }  
  45.     }  
  46. }  

而对于两个队列实现一个栈,想象如果我要把刚放的东西在取出来,对于队列来说,只能是把之前的东西都先出队,才能把刚才的放的东西出队。顺理成章,那就把之前的那些数据先出队到队列2中。两个队列来回交换数据即可。不在赘述。代码如下:

[java] view plaincopy
  1. import java.util.LinkedList;  
  2. import java.util.Queue;  
  3.   
  4.   
  5. public class MyStack {  
  6.     private Queue<String> queueFirst = new LinkedList<String>();  
  7.     private Queue<String> queueSecond = new LinkedList<String>();  
  8.       
  9.     public String push(String str){  
  10.         if(queueSecond.isEmpty()){  
  11.             queueFirst.offer(str);  
  12.         }else if(queueFirst.isEmpty()){  
  13.             queueSecond.offer(str);  
  14.         }  
  15.         return str;  
  16.     }  
  17.       
  18.     public String pop(){  
  19.         if(!queueFirst.isEmpty()){  
  20.             while(queueFirst.size() > 1){  
  21.                 queueSecond.offer(queueFirst.poll());  
  22.             }  
  23.             return queueFirst.poll();  
  24.         }else if(!queueSecond.isEmpty()){  
  25.             while(queueSecond.size() > 1){  
  26.                 queueFirst.offer(queueSecond.poll());  
  27.             }  
  28.             return queueSecond.poll();  
  29.         }  
  30.         return null;  
  31.     }  
  32.       
  33.     public boolean empty(){  
  34.         if(queueFirst.isEmpty() && queueSecond.isEmpty())  
  35.             return true;  
  36.         return false;  
  37.     }  
  38.       
  39.     public static void main(String[] args){  
  40.         MyStack stack = new MyStack();  
  41.         stack.push("hello");  
  42.         stack.push("baby");  
  43.         stack.push("!");  
  44.           
  45.         while(!stack.empty()){  
  46.             System.out.print(stack.pop());  
  47.         }  
  48.     }  
  49. }  
0 0
原创粉丝点击