栈和队列

栈,后进先出
队列,先进先出
1.数组实现栈

public class MyStack<E> {

    private Object[] stack;
    private int size;
    public MyStack(){
        stack=new Object[10];
    }

    public boolean isEmpty(){
        return size==0;
    }
    public E peek(){
        if(isEmpty()){
            return null;
        }
        return(E) stack[size-1];
    }
    public E pop(){
        E e=peek();
        stack[size-1]=null;
        size--;
        return e;
    }
    public E push(E item){
        ensureCapacity(size+1);
        stack[size++]=item;
        return item;
    }
    public void ensureCapacity(int size){
        int len=stack.length;
        if(size>len){
            int newLen=10;
            stack=Arrays.copyOf(stack,newLen);
        }
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MyStack<Integer> s=new MyStack<Integer>();
        s.push(1);
        s.push(2);
        System.out.println("栈中元素个数"+s.size);
        System.out.println("栈顶元素"+s.pop());
        System.out.println("栈中元素个数"+s.size);
        System.out.println("栈顶元素"+s.pop());
    }

}
/*
栈中元素个数2
栈顶元素2
栈中元素个数1
栈顶元素1
*/

2.链表实现栈

class Node<E>{
    Node<E> next=null;
    E data;
    public Node(E data){
        this.data=data;
    }
}

public class LinkedListStack<E> {
    Node<E> top=null;
    public boolean isEmpty(){
        return top==null;
    }
    public void push(E data){
        Node<E> newNode=new Node<E>(data);
        newNode.next=top;
        top=newNode;
    }
    public E pop(){
        if(this.isEmpty()){
            return null;
        }
        E data=top.data;
        top=top.next;
        return data;
    }
    public E peek(){
        if(isEmpty()){
            return null;
        }
        return top.data;
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MyStack<Integer> s=new MyStack<Integer>();
        s.push(1);
        s.push(2);
        System.out.println("栈顶元素"+s.pop());

    }

}

注意:该实现不是线程安全的,下面程序会讲到,要实现线程安全的栈,需要对入栈和出栈进行同步

3.用O(1)的时间复杂度求栈中最小元素

利用o(1)时间复杂度求栈中最小元素,遍历栈的时间复杂度为O(n);由于每次压栈和出栈都有可能改变栈中的min,增加一个存放min的栈。
空间换取时间:实现时使用两个栈结构,一个存储数据,一个存储栈的最小元素;如果当前入栈的元素比原来栈中的最小值还小,则把这个值压入保存最小值元素栈中;出栈时,如果当前出栈的元素恰好为当前栈中的min,保存最小值的栈顶元素也出栈

public class StackMin {

    MyStack<Integer> elem;
    MyStack<Integer> min;
    public StackMin(){
        elem=new MyStack<Integer>();
        min=new MyStack<Integer>();
    }
    public void push(int data){
        elem.push(data);
        if(min.isEmpty()){
            min.push(data);
        }
        else{
            if(data<min.peek()){
                min.push(data);
            }
        }
    }
    public int pop(){
        int topData=elem.peek();
        elem.pop();
        if(topData==this.min()){
            min.pop();
        }
        return topData;
    }
    public int min(){
        if(min.isEmpty()){
            return Integer.MAX_VALUE;
        }
        else{
            return min.peek();
        }
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        StackMin s=new StackMin();
        s.push(1);
        s.push(2);
        s.push(0);
        s.push(5);
        s.push(7);
//      for(int i=0;i<5;i++){
//          System.out.println(s.pop());
//      }
        System.out.println("栈min"+s.min());
    }

}

4.链表实现队列

public class MyQueue<E> {

    private Node<E> head=null;
    private Node<E> tail=null;
    public boolean isEmpty(){
        return head==tail;
    }

    public void put(E data){
        Node<E> newNode=new Node<E>(data);
        if(head==null&&tail==null){
            head=newNode;
            tail=newNode;
        }
        else{
            tail.next=newNode;
            tail=newNode;
        }
    }

    public E pop(){
        if(this.isEmpty()){
            return null;
        }
        E data=head.data;
        head=head.next;
        return data;
    }

    public int size(){
        Node<E> tmp=head;
        int n=0;
        while(tmp!=null){
            n++;
            tmp=tmp.next;
        }
        return n;
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MyQueue<Integer> q=new MyQueue<Integer>();
        q.put(1);
        q.put(2);
        q.put(3);
        System.out.println("队列长度"+q.size());
        System.out.println("队首元素"+q.pop());
        System.out.println("队首元素"+q.pop());

    }

}

5.数组实现队列

public class MyQueueArray <E>{
    private LinkedList<E> list=new LinkedList<E>();
    private int size=0;
    public synchronized void put(E e){
        list.addLast(e);
        size++;
    }
    public synchronized E pop(){
        size--;
        return list.removeFirst();
    }
    public synchronized boolean empty(){
        return size==0;
    }
    public synchronized int size(){
        return size;
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MyQueueArray<Integer> q=new MyQueueArray<Integer>();
        q.put(8);
        q.put(2);
        q.put(3);
        System.out.println("队列长度"+q.size());
        System.out.println("队首元素"+q.pop());
        System.out.println("队首元素"+q.pop());

    }

}

6.利用两个栈模拟队列操作

利用Java类库提供的Stack来实现:

package stack;
/*
 * 两个栈实现队列:A为入栈,B为出栈
 * 入栈,入A即可
 * 出栈,如果B不为空,直接弹出B中数据
 * 如果B空,依次弹出A中的数据放入B中,再弹出B中的数据
 */
import java.util.Stack;

public class StackQueue<E> {
    private Stack<E> sa=new Stack<E>();
    private Stack<E> sb=new Stack<E>();
    public synchronized void put(E e){
        sa.push(e);
    }
    public synchronized E pop(){
        if(sb.isEmpty()){
            while(!sa.isEmpty()){
                sb.push(sa.pop());
            }
        }
        return sb.pop();
    }
    public synchronized boolean empty(){
        return sa.isEmpty()&&sb.isEmpty();
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        StackQueue<Integer> sq=new StackQueue<Integer>();
        sq.put(2);
        sq.put(8);
        sq.put(5);
        System.out.println("队列首元素"+sq.pop());
        System.out.println("队列首元素"+sq.pop());

    }

}

7.利用两个队列实现栈

Queue是一个接口,已知的实现类有:ArrayDeque,LinkedList,SynchronousQueue等

package stack;
/*
 * 利用两个队列实现栈
 * q1入队列,q2出队列,s为栈
 * 要压栈,入队列q1即可
 * 弹栈,如果q1中只有一个元素,让q1中的元素出队列并输出即可
 * 如果q1不只一个元素,q1中所有元素出队列,入队列q2,最后一个元素不入队列q2输出该元素,然后将q2所有元素入q1
 */

import java.util.*;

public class QueueStack<Integer>{

    private LinkedList<Integer> q1=new LinkedList<Integer>();
    private LinkedList<Integer> q2=new LinkedList<Integer>();

    public synchronized void push(Integer item){
        q1.addLast(item);
    }

    public synchronized Integer pop(){
        Integer re=null;
        if(sSize()!=0){
            if(!q1.isEmpty()){
                toAnother();
                re=q1.removeFirst();
            }
            else{
                toAnother();
                re=q2.removeFirst();
            }
        }
        return re;
    }

    public void toAnother(){
        if(!q1.isEmpty()){
            while(q1.size()>1){
                q2.add(q1.removeFirst());
            }
        }
        else if(!q2.isEmpty()){
            while(q2.size()>1){
                q1.add(q2.removeFirst());
            }
        }
    }

    public int sSize(){
        return q1.size()+q2.size();
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        QueueStack stack=new QueueStack();  
        stack.push(1);  
        stack.push(2);  
        stack.push(3);  
        stack.push(4);  
        System.out.println(stack.pop());  
        System.out.println(stack.pop());  
        stack.push(5);  
        stack.push(6);  
        System.out.println(stack.pop());  
        System.out.println(stack.pop());  
        System.out.println(stack.pop());  
        System.out.println(stack.pop());  
        System.out.println(stack.pop()); 
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值