用栈来表示队列,用队列来表示栈
这个问题总的栈和队列,没有自己手写,自己手写太浪费了,于是就用的java中的集合框架list下面的LinkedList
其实LinkedList既可以当做栈用,也可以当做队列来使用.
作为栈的时候,LinkedList<T> stack = new LinkedList<T>().入栈stack.push(e),出栈stack.pop()
作为队列时,LinkedList<T> queue = new LinkedList<T>(),入队queue.offer(e),出队,queue.poll()
(1)使用两个栈来实现队列先进先出的功能,思想很简单:
1)两个栈都空的时候,表示队列是空的
2)入队操作,stack1.push(e)即可
3)出队操作,首先要判断是不是空队。负责出队的是stack2,出队之前先判断stack2是不是空的,如果是空的话,先把stack1中的元素出站,并依次压入到stack2中,然后stack2弹出栈顶元素即可。
直接看代码吧:
1 /** 2 * 使用两个 栈实现一个队列的功能 堆成的另一个问题 使用 两个队列实现一个栈 3 * @author Administrator 4 * 5 */ 6 public class StackQueue <T>{ 7 LinkedList<T> stack1; 8 LinkedList<T> stack2; 9 10 public StackQueue() {// 构造并初始化一个队列 11 stack1 = new LinkedList<T>(); 12 stack2 = new LinkedList<T>(); 13 } 14 15 /** 16 * 判断队列是否为空 17 * @return 18 */ 19 public boolean isEmpty() { 20 if(stack1.isEmpty() && stack2.isEmpty()) 21 return true; 22 else return false; 23 } 24 25 public int getLength() 26 { 27 return stack1.size() + stack2.size(); 28 } 29 30 /** 31 * 入队操作 32 * @param e 33 */ 34 public void offer(T e) { 35 // TODO Auto-generated method stub 36 stack1.push(e); 37 } 38 39 /** 40 * 出队操作 41 * @return 42 */ 43 public T poll() 44 { 45 if(stack1.isEmpty() && stack2.isEmpty()) 46 throw new RuntimeException(new Exception("queue is empty")); 47 else 48 { 49 if(stack2.isEmpty())//如果stack2empty要先把stack1中的元素出站并依次压入stack2 50 { 51 while(stack1.isEmpty()==false) 52 { 53 stack2.push(stack1.pop()); 54 } 55 } 56 return stack2.pop(); 57 } 58 } 59 60 public static void main(String[] args) { 61 StackQueue<Integer> sq = new StackQueue<Integer>(); 62 63 System.out.println("sq is empty? :"+sq.isEmpty()); 64 65 sq.offer(1); 66 sq.offer(2); 67 sq.offer(3); 68 sq.offer(4); 69 sq.offer(5); 70 71 System.out.println("sq.length : "+sq.getLength()); 72 System.out.println("sq is empty? :"+sq.isEmpty()); 73 74 while(!sq.isEmpty()) 75 { 76 System.out.print(sq.poll()+","); 77 } 78 System.out.println(); 79 } 80 }
(2)使用两个队列实现栈的先进后出的功能
1)两个队列都空的时候表明栈空
2)始终保持queue1为空,用来入栈,如果queue1不空,的话,可以把queue1中的元素依次出队并且依次进入到queue2队中,然后返回queue2的尾元即可。这里使用java的LinkedList可以取巧,具体可以直接看下卖弄的代码:
1 /** 2 * 使用两个队列 实现 队列的操作 3 * 因为使用的是两个链队实现的 所以这个栈有空的时候,但是不需要判断满 4 * @author Administrator 5 * 6 */ 7 public class QueueStack <T>{ 8 LinkedList<T> queue1 ; 9 LinkedList<T> queue2 ; 10 11 public QueueStack() { //初始化一个空队列 12 queue1 = new LinkedList<T>(); 13 queue2 = new LinkedList<T>(); 14 } 15 16 /** 17 * 判断是不是一个空栈 18 * @return 19 */ 20 public boolean isEmpty() 21 { 22 if(queue1.isEmpty()&&queue2.isEmpty()) 23 return true; 24 else 25 return false; 26 } 27 28 /* 29 * 获取栈的大小 30 */ 31 public int getLength() 32 { 33 return queue1.size() + queue2.size(); 34 } 35 36 /* 37 * 入栈操作 直接让元素进第一个队 38 */ 39 public void push(T e) 40 { 41 queue1.offer(e); 42 } 43 44 /** 45 * 出站操作 46 * @return 47 */ 48 public T pop() 49 { 50 LinkedList<T> tmp; //始终保持让queue1 为空 准备入栈,让queue2完成出站 51 52 if(queue1.isEmpty() && queue2.isEmpty()) 53 { 54 throw new RuntimeException(new Exception("stack is empty")); 55 } 56 57 if(!queue1.isEmpty()){ 58 tmp = queue2; 59 queue2 = queue1; 60 queue1 = tmp; 61 }// 于是 queue1变成了 queue2,这样就可以再次入栈了,线面使用queue2实现出站 62 63 /* 64 * 出栈的操作就是把queue2中的 元素依次出去,最后剩一个元素 就是需要出站的元素, 65 * 这里可以取巧一下直接获取 queue2.last的元素作为返回值 66 */ 67 T e = queue2.peekLast(); 68 queue2.removeLast(); 69 return e; 70 } 71 72 public static void main(String[] args) { 73 QueueStack<Integer> qs = new QueueStack<Integer>(); 74 75 System.out.println("qs is empty?:"+qs.isEmpty()); 76 77 System.out.println("push 1,2,3"); 78 79 qs.push(1); 80 qs.push(2); 81 qs.push(3); 82 83 System.out.println("qs length :"+qs.getLength()); 84 System.out.println("qs is enpty:"+qs.isEmpty()); 85 86 System.out.print("pop one by one:"); 87 while(!qs.isEmpty()) 88 { 89 System.out.print(qs.pop()+","); 90 } 91 System.out.println(); 92 93 qs.pop(); 94 95 } 96 }