数据结构之栈和队列

来源:互联网 发布:网络直播股票 编辑:程序博客网 时间:2024/05/01 10:59

栈和队列篇

先进后出

用数组实现栈

public class StackByArray<E> {      // 栈的长度      private int length;      // 栈      private Object[] array;      // 栈顶的下标      private int topIndex = -1;      /**      * StackByArry:构造方法      */      public StackByArray(int length) {          this.length = length;          array = new Object[length];      }      /**      * push:入栈      */      private void push(E e) throws Exception {          if(isFullStack()) {              throw new Exception("栈已满");          }        array[++topIndex] = e;      }      /**      * top: 取出栈顶元素      */      private E top() throws Exception {          if(isEmpty()) {              throw new Exception("栈为空");          }          E top_elem = (E)array[topIndex];          return top_elem;      }      //出栈    private void pop() throws Exception {        if(isEmpty()) {              throw new Exception("栈已空");          }          array[topIndex] = null;          topIndex--;    }    //清空栈    private void clear() {        Arrays.fill(this.array, null);        this.topIndex=-1;        this.array=new Object[this.length];    }    /**      * isEmptyStack:判断栈是否为空      */      private boolean isEmpty() {          return (topIndex == -1);      }      /**      * isFullStack:判断栈是否已满      */      private boolean isFullStack() {          return topIndex == (length - 1);      }      /**      * getLength:取得栈内的数据长度      */      private int getLength() {          return topIndex + 1;      }      /**      * outPut:栈内容输出      */      private void outPut() {          for(Object obj : array) {              if(obj != null) {                  System.out.print(obj + "  ");              }          }          System.out.println();      }      public static void main(String[] args) throws Exception {          StackByArray<Integer> stack = new StackByArray<Integer>(10);          for(int i = 1; i <= 8; i++) {              stack.push(i);          }          stack.outPut();        System.out.println(stack.top());         stack.pop();        System.out.println(stack.getLength());         stack.clear();        stack.top();    }  }  /*输出:1  2  3  4  5  6  7  8  87Exception in thread "main" java.lang.Exception: 栈为空    at datastructure.StackByArray.top(StackByArray.java:52)    at datastructure.StackByArray.main(StackByArray.java:123)    */

用链表实现栈

链表实现的栈,结点易扩展,不会满

head只是标记下头结点,在栈的实现中没有用

每次新建一个结点(newNode),都使其指向链表最后的结点(current),如此最后添加的结点肯定在链表尾,弹出时依次访问之前的结点(pre),便可维护一个栈

这里pop(),会弹出栈顶元素

public class StackByLink<E> {    private Node head;    private Node current;    class Node{        E data;        Node pre;        public Node(E data){            this.data=data;        }    }    //入栈    public void push(E data){        if(head==null){            head=new Node(data);            current=head;        }        else{            Node node= new Node(data);            node.pre=current;            current=node;        }    }    public E pop()throws RuntimeException{        if(current==null)             throw new RuntimeException("栈已空");        Node node=current;        current=current.pre;        return node.data;    }    public Node top(){        if(current==null)            throw new RuntimeException("栈已空");        return current;    }    public static void main(String[] args) {        StackByLink<Integer> stack= new StackByLink<Integer>();        stack.push(1);        stack.push(4);        stack.push(8);        System.out.println(stack.pop());        System.out.println(stack.pop());        System.out.println(stack.pop());        System.out.println(stack.pop());    }}/*输出:841Exception in thread "main" java.lang.RuntimeException: 栈已空    at datastructure.StackByLink.pop(StackByLink.java:46)    */

两个队列实现一个栈

思路:

将1、2、3依次入队列一, 然后将最后加入的3留在队列一,将1,2入队列二,将3出队列一,此时队列一空了,然后把队列二中的所有数据入队列一;将最上面的2留在队列一,将下面的1入队列二。。。依次循环。

public class StackByDoubleQueue<E>{    Queue<E> queue1 = new ArrayDeque<E>();    Queue<E> queue2 = new ArrayDeque<E>();    public void push(E e){        queue1.add(e);    }    public E pop() throws RuntimeException{        E data;        if(queue1.size()==0)            throw new RuntimeException("栈为空");        while(queue1.size()!=0){            if(queue1.size()==1){                data=queue1.poll();                while(queue2.size()!=0){//把queue2的全部数据放到队列一中                    queue1.add(queue2.poll());                }                return data;            }            queue2.add(queue1.poll());        }        throw new RuntimeException("栈为空");    }    public static void main(String[] args) {        StackByDoubleQueue<Integer> stack = new StackByDoubleQueue<Integer>();        stack.push(1);        stack.push(4);        stack.push(8);        System.out.println(stack.pop());        System.out.println(stack.pop());        stack.push(9);        System.out.println(stack.pop());        System.out.println(stack.pop());    }}

最小栈

这里需要加一个辅助栈,用空间换取时间。辅助栈中,栈顶永远保存着当前栈中最小的数值。具体是这样的:原栈中,每次添加一个新元素时,就和辅助栈的栈顶元素相比较,如果新元素小,就把新元素的值放到辅助栈中,如果新元素大,就把辅助栈的栈顶元素再copy一遍放到辅助栈的栈顶。

public class MinStack {    private Stack<Integer> stack = new Stack<Integer>();//这里不再用泛型,因为需要比较    private Stack<Integer> minStack = new Stack<Integer>();    public void push(int data){        stack.push(data);        if(minStack.size()==0||data<minStack.peek()){            minStack.push(data);        }        else            minStack.push(minStack.peek());    }    public int pop() throws RuntimeException{        if(stack.size()==0){            throw new RuntimeException("栈已空");        }        int data=stack.pop();        minStack.pop();        return data;    }    public int getMin() throws RuntimeException{            if(minStack.size()==0)                throw new RuntimeException("栈已空");            return minStack.peek();    }    public static void main(String args[]) throws RuntimeException{        MinStack stack=new MinStack();        stack.push(4);        stack.push(8);        System.out.println(stack.getMin());        stack.pop();        stack.push(1);        System.out.println(stack.getMin());    }}/*输出:41*/

栈的压入、弹出序列

题目描述

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。

import java.util.ArrayList;import java.util.Stack;public class Solution {    public boolean IsPopOrder(int [] pushA,int [] popA) {      if(pushA.length==0)          return false;      Stack<Integer> stack = new Stack<Integer>();        int j=0;       for(int i=0;i<pushA.length;i++){           stack.push(pushA[i]);           while(!stack.empty()&&stack.peek()==popA[j]){               j++;               stack.pop();           }       }        if(j==popA.length)            return true;        else            return false;    }}

队列

用数组实现队列

先进先出

public class QueueByArray<E> {    private int length;    private Object[] array;    private int front;    private int rear;    public QueueByArray(int length){        this.length=length;        this.array=new Object[length];        front=0;        rear=0;    }    public boolean isEmpty(){        return front==rear;    }    public boolean isFull(){        return array.length==rear;    }    //向队尾插入元素    public void push(E e){        if(isFull())            throw new RuntimeException("队列已满");        else            array[rear++]=e;    }    //获得队头元素    public E top(){        if(isEmpty())            throw new RuntimeException("队列为空");        return (E)array[front];    }    public void pop(){        if(isEmpty())            throw new RuntimeException("队列为空");        front++;    }    public void output(){        for(Object obj:array)            if(obj!=null)                System.out.print(obj+" ");        System.out.println();    }    public static void main(String args[]){        QueueByArray<String> queue= new QueueByArray<String>(2);        queue.push("Hello");        queue.push("World");        queue.output();        System.out.println(queue.top());        queue.pop();        System.out.println(queue.top());        queue.pop();        queue.pop();    }}/*输出:Hello Exception in thread "main" World HelloWorldjava.lang.RuntimeException: 队列为空    at datastructure.QueueByArray.pop(QueueByArray.java:62)    at datastructure.QueueByArray.main(QueueByArray.java:85)    */

参考

用链表创建队列

新建一个结点,使当前结点(current)的next指向它
弹出时,从head向后遍历弹出

public class QueueByLink<E> {    private Node head;    private Node current;    class Node{        E data;        Node next;        public Node(E data){            this.data=data;        }    }    public void push(E data){        if(head==null){            head = new Node(data);            current=head;        }        else{            current.next=new Node(data);            current=current.next;        }    }    public E pop() throws RuntimeException{        if(head==null)             throw new RuntimeException("队列为空");        Node node =head;        head=head.next;        return node.data;    }    public static void main(String[] args) {        QueueByLink<Integer> queue=new QueueByLink<Integer>();        queue.push(1);        queue.push(4);        queue.push(8);        System.out.println(queue.pop());        System.out.println(queue.pop());        System.out.println(queue.pop());        System.out.println(queue.pop());    }}/*输出:148Exception in thread "main" java.lang.RuntimeException: 队列为空    at datastructure.QueueByLink.pop(QueueByLink.java:43)    at datastructure.QueueByLink.main(QueueByLink.java:57)    */

两个栈实现一个队列

思路:
栈1用于存储元素,栈2用于弹出元素,负负得正。

说的通俗一点,现在把数据1、2、3分别入栈一,然后从栈一中出来(3、2、1),放到栈二中,那么,从栈二中出来的数据(1、2、3)就符合队列的规律了,即负负得正。

public class QueueByDoubleStack<E>{    private Stack<E> stack1=new Stack<E>();    private Stack<E> stack2 = new Stack<E>();    public void push(E data){        stack1.push(data);    }    public E pop() throws RuntimeException{        if(stack2.empty()){//stack1中的数据放到stack2之前,        //先要保证stack2里面是空的,每次出队列之前,都要把stack1中的数据完全倾入stack2            while(!stack1.empty()){                stack2.push(stack1.pop());            }           }        if(stack2.empty())//若stack2为空,即stack1,stack2都为空,或stack2中的数据出完了            throw new RuntimeException("队列为空");        return stack2.pop();    }    public static void main(String[] args) {        QueueByDoubleStack<Integer> queue=new QueueByDoubleStack<Integer>();        queue.push(1);        queue.push(4);        queue.push(8);        System.out.println(queue.pop());        queue.push(9);        System.out.println(queue.pop());        System.out.println(queue.pop());        System.out.println(queue.pop());    }}/*输出:1489Exception in thread "main" java.lang.RuntimeException: 队列为空    at datastructure.QueueByDoubleStack.pop(QueueByDoubleStack.java:40)    at datastructure.QueueByDoubleStack.main(QueueByDoubleStack.java:56)    */
0 0
原创粉丝点击