栈和队列第二弹,完结篇(一)

简介: 栈和队列第二弹,完结篇


💛1.队列的基本底层实现

public class MyQueue {
    int array[];
    int usedsize=0;
    public MyQueue(){
        this.array=new int [5];
    }

💙2.判断是否满,满了需要扩容      

Arrays.copyOf(数组,数组的长度);我常常会忘记哈哈哈哈哈

 //判满
    public  void  ifFull(){
        if(usedsize==5)
        array=Arrays.copyOf(this.array,array.length*2);
    }

💜3.判断是否为空

 //是否为空
    public boolean isEmpty(){
        if(usedsize==0){
            return true;
        }
        return false;
    }

❤️4.添加元素

    //添加元素
    public void add(int data){
        ifFull();             //满了就扩容
        usedsize++;
        array[usedsize-1]=data;
    }

💚5.查找队首元素

 //查看队首元素
    public int  element(){
        return array[0];
    }

💓 6.出队

  //出队
    public int poll(){
        int m=array[0];
        for(int i=1;i<usedsize;i++){
            array[i-1]=array[i];
        }
        usedsize--;
        return array[0];
    }

💕7.遍历元素个数

//遍历队列元素
    public void display(){
        for(int i=0;i<usedsize;i++){
            System.out.println(array[i]);
        }
    }

栈的集合基本操作

offer(x);把x元素插入到队列里面

poll():弹出栈顶元素,并且返回该值

其他与栈相同,peek,isEmpty,

注意还有一个size()这个方法也容易忽视。:返回队列数值

一、

💛

最小栈

1.说简单也很简单,就是可能在一些小细节方面进坑,比如说插入元素,就容易没想那么多,导致多插入一次;(🌚 🌚 🌚 又是一下午的经验之道)

简单讲一下我的思路点:刚开始肯定都是没思路,我就开始一个一个慢慢写,为什么是两个栈,因为他要求找到最小的元素要求时间复杂度是O(1),所以要有第二个栈,然后栈肯定,他需要有一定特殊性,才能出栈是最小的,但是他假如只有一个,那她最小的肯定就是他,所以最小栈肯定要入他,剩下的就要找还有什么类型的需要进来,

看下图👋,5和2,哪个应该进来,肯定是2应该进来,因为2小啊。我就是为了找最小值

,只有删除和新增有点难度,其余的就不谈了,没啥必要。

⭐️ 🌟 💫 还有一个问题你要想清楚,我们弹出栈的时候,最小栈应该怎么办,

看下面图,假如是图1:他的最小栈应该是是只有1。图二应该是有1,2,4,

拿图2举例子,开始弹出1,然后最小栈的栈顶也是1,然后最小栈也开始弹,开始弹出3,然后最小栈的栈顶不是3,那么就原始栈弹,最小栈不弹,换句话说:一样就弹出,不一样的不用弹出。

class MinStack {
    private Stack<Integer> data;
    private Stack<Integer> minStack;
    public MinStack() {
          data=new Stack<>();
          minStack=new Stack<>();
    } 
    public void push(int val) {
        data.push(val);
    if(minStack.isEmpty()){
        minStack.push(val);
    }
    else if(minStack.peek()>=val){         //这个很关键,一定要是else 
        minStack.push(val);                //避免插入的时候,有可能进入一次这个,会再次插入
    } 
    }
    public void pop() {
        int pop=data.pop();
        int top=minStack.peek();
     if(pop==top){
           minStack.pop();
     }
    }
    public int top() {
        return data.peek();
    }
    public int getMin() {
       return minStack.peek();
    }
}

二、

💙

2.用队列实现栈: 解法一通过一个栈,来实现,首先,一个栈的基本操作是压栈,弹栈,是否为空,返回栈顶操作(队列是进队从尾巴进,出队从头出)弹出栈顶也就是4,那么弹出4的话那么队列的队头也是4,他的弹栈操作就实现了,那么返回栈顶也实现了,空肯定也实现了,那么我们目前最大的问题就是如何把这个1队列逆置过来,让他变成2的:1,2,3,4呢。

把它用递归的想法去想,他只有一个队列,然后只有一个的时候,不逆置(size在插入之前的个数),所以从i=0;size=0刚开始为1开始,假如插入一个size停留在插入之前也就是1,也相对应他需要调整逆置一次,重新吧1插入,形成:2,1 💗 1,2的逆置变化。然后当他是3的时候(1,2,需要被逆置)所以,(注意哈,❗️❗️❗️他并不是从3,2,1开始换,而是从3,1,2开始换,)只需要换两次。~~~以此类推。

class MyStack {
    Queue<Integer>stack1;
    public MyStack() {
    stack1=new LinkedList<Integer>();
    }
    public void push(int x) {
        int n=stack1.size();
         stack1.offer(x);
        for (int i = 0; i < n; i++) {
            stack1.offer(stack1.poll());
        }
    }
    public int pop() {
        return stack1.poll();
    }
    public int top() {
     return stack1.peek();
    }
    public boolean empty() {
    return stack1.isEmpty();
    }
}

💚

解法2:

用两个队列:两个队列就是思路是先从出队和入队开始思考,假如说要出队,那么就需要把除了队尾元素以外的全部拿出来,放到那个空的队列中,然后剩下的一个就是队尾(也就是要出的栈顶),那么插入的时候:我们就需要看哪个是空的,哪个里面有数,假如说里面有东西,就插入非空的队列(里面有东西的),要是两个都是空,那么随便插入一个。

class MyStack{ 
        Queue<Integer>stack1;
        Queue<Integer> stack2;
        public MyStack() {
            stack1=new LinkedList<Integer>();
            stack2=new LinkedList<Integer>();
        }
        public void push(int x) {
            if((stack1.isEmpty())&&!(stack2.isEmpty())){
                stack2.offer(x);
            }
            if(!(stack1.isEmpty())&&(stack2.isEmpty())){
                stack1.offer(x);
            }
             if(stack1.isEmpty()&&stack2.isEmpty()){
                stack1.offer(x);
            }
        }
        public int pop() {
            if((stack1.isEmpty())&&(!stack2.isEmpty())){
                int a=stack2.size();
                while(a>1){
                    stack1.offer(stack2.poll());
                    a--;                   //除了最后一个,全部移动到另一个队列中
                }
                return stack2.poll();     //删除
            }
            else   if((!stack1.isEmpty())&&(stack2.isEmpty())){
                int a=stack1.size();
                while(a>1){
                    stack2.offer(stack1.poll());
                    a--;
                }
                return stack1.poll();
            }
            else{ return -1; }
        }
        public int top() {
            if((stack1.isEmpty())&&(!stack2.isEmpty())){
                int a=stack2.size();
                while(a>1){
                    stack1.offer(stack2.poll());
                    a--;
                }
                int c=stack2.peek();         //最后一个剩余的元素,需要存起来,放回到和其他元素在一起
                stack2.poll();
                stack1.offer(c);
                return c;
            }
            if((!stack1.isEmpty())&&(stack2.isEmpty())){
                int a=stack1.size();
                while(a>1){
                    stack2.offer(stack1.poll());
                    a--;
                }
                int c=stack1.peek();
                stack1.poll();
                stack2.offer(c);
                return c;
            }
            else {
                return -1;
            }
        }
        public boolean empty() {
            return stack1.isEmpty()&&stack2.isEmpty();       //两个都是空,才真正是空
        }
    }



目录
打赏
0
0
0
0
27
分享
相关文章
|
2月前
|
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
158 77
|
8天前
|
STL——栈和队列和优先队列
通过以上对栈、队列和优先队列的详细解释和示例,希望能帮助读者更好地理解和应用这些重要的数据结构。
24 11
☀☀☀☀☀☀☀有关栈和队列应用的oj题讲解☼☼☼☼☼☼☼
### 简介 本文介绍了三种数据结构的实现方法:用两个队列实现栈、用两个栈实现队列以及设计循环队列。具体思路如下: 1. **用两个队列实现栈**: - 插入元素时,选择非空队列进行插入。 - 移除栈顶元素时,将非空队列中的元素依次转移到另一个队列,直到只剩下一个元素,然后弹出该元素。 - 判空条件为两个队列均为空。 2. **用两个栈实现队列**: - 插入元素时,选择非空栈进行插入。 - 移除队首元素时,将非空栈中的元素依次转移到另一个栈,再将这些元素重新放回原栈以保持顺序。 - 判空条件为两个栈均为空。
|
2月前
|
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
52 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
|
2月前
|
【C++数据结构——栈与队列】链栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现链栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储整数,最大
51 9
|
2月前
|
C++
【C++数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】
【数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】(1)遇到左括号:进栈Push()(2)遇到右括号:若栈顶元素为左括号,则出栈Pop();否则返回false。(3)当遍历表达式结束,且栈为空时,则返回true,否则返回false。本关任务:编写一个程序利用栈判断左、右圆括号是否配对。为了完成本关任务,你需要掌握:栈对括号的处理。(1)遇到左括号:进栈Push()开始你的任务吧,祝你成功!测试输入:(()))
45 7
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
106 5
|
4月前
|
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
386 9
|
4月前
|
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
64 1
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。
130 21