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

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


💛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();       //两个都是空,才真正是空
        }
    }



相关文章
|
1月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
210 9
|
1月前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
37 1
|
27天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
53 5
|
1月前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。
|
1月前
|
存储 JavaScript 前端开发
执行上下文和执行栈
执行上下文是JavaScript运行代码时的环境,每个执行上下文都有自己的变量对象、作用域链和this值。执行栈用于管理函数调用,每当调用一个函数,就会在栈中添加一个新的执行上下文。
|
1月前
|
存储
系统调用处理程序在内核栈中保存了哪些上下文信息?
【10月更文挑战第29天】系统调用处理程序在内核栈中保存的这些上下文信息对于保证系统调用的正确执行和用户程序的正常恢复至关重要。通过准确地保存和恢复这些信息,操作系统能够实现用户模式和内核模式之间的无缝切换,为用户程序提供稳定、可靠的系统服务。
52 4
|
1月前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
1月前
|
算法
数据结构之购物车系统(链表和栈)
本文介绍了基于链表和栈的购物车系统的设计与实现。该系统通过命令行界面提供商品管理、购物车查看、结算等功能,支持用户便捷地管理购物清单。核心代码定义了商品、购物车商品节点和购物车的数据结构,并实现了添加、删除商品、查看购物车内容及结算等操作。算法分析显示,系统在处理小规模购物车时表现良好,但在大规模购物车操作下可能存在性能瓶颈。
49 0
|
2月前
数据结构(栈与列队)
数据结构(栈与列队)
23 1
|
2月前
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
48 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器

热门文章

最新文章