数据结构(data structure)(3)栈和队列

栈的定义

stack有称堆栈
栈顶top
栈顶元素
栈底bottom
空栈
进展或入栈
出栈或退栈

Last In First Out
LIFO后入先出

public interface IStack<T> extends MysList<T>{
   // 元素入栈
   void push(e);
    //出栈
   T pop(){};
   //判空
   boolean empty();
    //栈的大小
   int getSize();
}

public class ListNode<T>{
    T data;
    ListNode<T> pre;
    ListNode<T> next;

    public ListNode(T data){this.data=data;}

    public T getData(){return data;}

    public ListNode<T> getPre(){return pre;}

    public void setNext(ListNode<T> next){this.next=next;}

    public void setPre(ListNode<T> pre){this.pre=pre;}

}

public class MyStack<T>extends DOubleLinked<T>implements IStack<T>{

    public void push(T e){
        super.add(e);
    }

    public T pop(){
     if(size==0)throw new EmptyStackException();
     ListNode<T> the =super.last.getPre();
     T res=the.getData();

    the.getPre().setNext(last);
    last.setPre(the.getPre());
    the.setNext(null);
    the.setPre(null);
    size--;
    return res;

    }

    public boolean empty(){
    return getSize()==0;
    }

    public int getSize(){return super.getSize();}

}

队列的实现

 

queue
队尾入,队首出
入队,出队
队尾元素,对首元素
先进先出
First In First Out(FIFO)


public interface IQueue<T>{
    //入队
    void enquque(T e);
    //出队
    T dequque();
    //返回队列的大小
    int getSize();
    //判断是否为空
    boolean empty();
    //取队首元素
    T peek();

}

public class MyQueue<T> extends DoubleLinkedList<T> implements IQueue{
    public void  enqueue(T e){
        super.add(e);
    }

    public T dequeue(){
        ListNode h=first.getNext();
        first.setNext(h.getNext());
        h.getNext().setPre(first);
        h.setPre(null);
        h.setNext(null);
        size--;
        return h.getData;
    }

    public boolean empty(){
    return getSize()==0;
    }

    public T peek(){
    return first.getNext.getData();
    }
}

栈和队列的例题

如何用一个数组来实现三个栈
记录三个栈顶的下标
//栈中实现min方法,可取出栈中最小值
public Int min(){
    ListNode<T> h=first.getNext();
    int min=-1;
    while(h!=last){
        if((int)h.getData()<min){
            min=(int)h.getData();
        }
    }
    return min;
}

//再创一个栈,记录最小值,保证每次入栈的都是当前栈里的最小值
public void push(Integer e){
    supper.add(e);
    if(brother.empty()){
    brother.push(e);
    }else{
     Integer peek=brother.peek();
     if(e<peek){
     brother.push(e);
     }else{
        brother.push(peek);
     }
    }
}

public Integer pop(){
    if(size<=0)throw new EmptyStackException();
    ListNode<Integer> the=super.last.getPre();
    Integer res=the.getData();

    the.getPre().setNext(last);
    last.setPre(the.getPre());
    the.setNext(null);
    the.setPre(null);
    size--;
    brother.pop();
    return res;
}

实现setOfStacks

 

setOfStacks由多个栈组成,前一个栈填满时新建一个栈,

给定一个操作序列int[][2] ope,每个操作的第一个数代表操作类型
若为1,则为push操作,后一个数为应push的数字
若为2,则为pop操作,后一个数字无意义
请返回一个int[][](c++为vector&ltvector&ltint>>),为完成所有操作后的setOfStacks,顺序为从下到上,默认初始的setOfStacks为空
保证数据合法

public ArrayList<ArrayList<Integer>>setOfStacks(int[][] ope,int size){
        ArrayList<ArrayList<Integer>>res=new ArrayList<>();
        ArrayList<Integer> currStack=new ArrayList<>(size);
        res.add(currStack);
        for(int[] opAndValue:ope){
            int op=opAndValue[0];
            int value=opAndValue[1];
            if(op==1){
                if(currStack.size()==size){//当前满
                currStack=new ArrayList<Integer>(size);//创建一个新的栈
                res.add(currStack);
                }
                currStack.add(value);
            }else{//出栈
                if(currStack.size()==0){
                res.remove(currStack);//栈的列表中移除
                currStack=res.get(res.size()-1);//被操作的栈是列表中的上一个栈
                }//线性表的下标是从0开始的
                currStack.remove(currStack.size()-1);
            }

        }
}


两个栈来实现一个队列
先将元素压入一个栈,当要取元素时,将元素出栈压入另一个栈,再出栈,即可得到队列

 public class SQueueByTwoStakc{
    Stack<Integer> stack1=new Stack();
    Stack<Integer> stack2=new stack();

    public  void enqueue(int node){
        if(stack1.isEmpty())}
          move(stack2.stack1);
        }
        stack1.push(node);
    }
    public int dequeue(){
    move(stack1,stack2);
    int result=stack2.pop();
    move(stack2,stack1);
    return result;
    }

    private void move(Stack source,Stack target){
        while(!source.empty()){
        target.push(source.pop());
        }
    }
 }


请编写一个程序,按升序对栈进行排序

 

请编写一个程序,按升序对栈进行排序,(即最大元素位于栈顶),要求最多只能使用一个额外的栈存放临时数据,但不得将元素复制到别的数据结构中
给定一个int[] number,其中第一个元素为栈顶,请返回排序后的栈,请注意这是一个栈,意味着排序过程中你只能访问到第一个元素
[1,2,3,4,5]
返回:[5,4,3,2,1]

public class TowStacksSort{
    //初始化原始栈
    Stack<Integer>source=new  Stack<>();
    for(int i=numbers.length;i>=0;i--){
        source.push(numbers[i]);
    }

    Stack<Integer> target=towStackSort(source);
    ArrayList<Integer> list=new ArrayList<>();
    while(!target.empty()){
        list.add(target.pop());
    }
    return list;
}


private void sortToTarget(Stack<Integer>source,Stack<Integer> target){
        while(!source.empty()){
            int v1=source.pop();//揭开盖子
            if(target.empty()){
                target.push(v1);
            }else{
            int v2=target.peek();
            if(v1>=v2){//盖子大,直接放入
            target.push(v1);
            }else{//盖子小,把大的往回收
            source.push(target.pop());

            while(!target.empty()&&v1<target.peek()){
            source.push(target.pop());
            }//直到盖子比peek大

            target.push(v1);//放入盖子
            }

            }
        }
}

猫狗收容所

 

有家动物收容所只收留猫和狗,担忧特殊的收养规则,收养人有两种或收养方式
第一种为直接收养所有动物中最早进入收容所的
第二种为选择收养的动物类型(猫或狗),并收养该种动物中最早进入收容所的

给定一个操作系统(int[][2] ope)代表所有时间
若第一个元素为1,则代表有动物进入收容所,第二个元素为动物的编号,正数代表狗,负数代表猫
若第一个元素为2,则代表有人收养动物i,,第二个元素若为0,则采取第一种收养方式(最早)
若为1,则指定收养狗,若为-1,则指定收养猫
请按顺序返回收养的序列,若出现不合法的操作,则没有可以复合领养要求的动物,则将这次领养操作忽略
[1,1],[1,-1],[2,0],[2,-1]

返回:[1,-1]

public class CatDogAsylum{
        private static class Animal{
        int type;
        int time;
        static int timeline;//全局变量,记录动物的时间点

        public Animal(int typeNumber){
           this.type=typeNumber;
            this.time=timeline++;
        }
        }

       public ArrayList<Integer> asylum(int[][] ope){

            ArrayList<Integer>res=new ArrayList<>();

            Queue<Animal> cats=new LinkedList<>();
            Queue<Animal> dogs=new LinkedList<>();

            for(int[] row:ope){
                int p=row[0];
                int typeNumber=row[1];
                if(op==1){//增加
                    if(typeNumber>0){
                    dogs.add(new Animal(typeNumber));
                    }
                    if(typeNumber<0){
                    cats.add(new Animal(typeNumber));
                    }
                }else if(op==2){//减少
                    if(typeNumber==0){//从两个队列中选timeline最小的
                        if((!dogs.isEmpty())&&(cats.isEmpty()||dogs.peek().time<cats.peek().time)){
                            res.add(dogs.poll().type);
                        }
                         else if((!cats.isEmpty())&&(dogs.isEmpty()||dogs.peek().time<cats.peek().time)){
                            res.add(cats.poll().type);
                        }
                          else{//用户指定了类型
                            if(typeNumber==1&&!dogs.isEmpty()){
                          res.add(dogs.poll().type);
                          }

                           if(typeNumber==-1&&!cats.isEmpty()){
                            res.add(cats.poll().type);
                            }
                        }
                    }else{
                    break;
                    }
                }
                return res;
            }
       }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值