当前位置: 首页 > wzjs >正文

网站建设怎么做平台开发火星时代教育培训机构学费多少

网站建设怎么做平台开发,火星时代教育培训机构学费多少,岳阳网站开发公司,深圳龙华建网站目录 栈(Stack) 概念 栈的使用 栈的模拟实现 栈的应用场景 1. 改变元素的序列 ​编辑 2. 将递归转化为循环 3. 括号匹配 4. 逆波兰表达式求值 ​编辑 5. 出栈入栈次序匹配 6. 最小栈 概念区分 队列(Queue) 概念 队列的使用 队列模拟实现 循环队列 双端队列…

目录

栈(Stack)

概念

栈的使用

栈的模拟实现

栈的应用场景

1. 改变元素的序列

​编辑

2. 将递归转化为循环

3. 括号匹配

4. 逆波兰表达式求值

​编辑

5. 出栈入栈次序匹配

6. 最小栈

概念区分

队列(Queue)

概念

队列的使用

队列模拟实现

循环队列

双端队列 (Deque)

面试题

1. 用队列实现栈

2. 用栈实现队列


栈(Stack)

概念

:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据在栈顶。

:上述两幅图示是为了理解栈的机制的。


栈的使用

public class Test {/*** 这是使用栈底层代码生成的测试文件* @param args*/public static void main(String[] args) {/*** 栈的一些方法的实现*/Stack<Integer> stack = new Stack<>();   // 构造一个栈对象出来// 往栈里面放元素【原则:先进的后出】stack.push(12);stack.push(23);stack.push(34);stack.push(45);   // 通过这个往栈里面添加元素,其中栈底为最先放的那个[12],栈顶为最后放的那个[45]// 从栈顶弹出元素[删除]int number1 = stack.pop();System.out.println(number1);   // 结果就是45// 获取栈顶元素【只是获取,但并不删除】System.out.println(stack);  // 先打印看一下栈里面有哪些元素int number2 = stack.peek();System.out.println(number2);System.out.println(stack);  // 再打印一下这个栈,验证一下是否被删除// 看一下栈是否为空boolean result1 = stack.empty();System.out.println(result1);// 再把栈中的元素全部删完stack.pop();stack.pop();stack.pop();// 这个时候再看一下栈是否为空boolean result2 = stack.empty();System.out.println(result2);// 获取栈的长度【因为刚刚已经把栈中的元素删完了,所以这里需要往栈里面添加一些元素】stack.push(99);stack.push(101);stack.push(103);stack.push(105);// 一共是添加了4个元素,接下来验证一样是不是4个元素int ret = stack.size();System.out.println(ret);}

上述代码就是对栈的一些方法进行一些简单的测试


栈的模拟实现

下述代码是我们自己模拟实现的一个的方法:

package stack_queue;import java.util.Arrays;public class Mystack {private int[] elem;private int usedSize;private static final int DEFAULT_CAPACIPY = 10;  // 默认数组的长度是10// 再来提供一个构造方法public Mystack(){this.elem = new int[DEFAULT_CAPACIPY];}/*** 入栈方法* @param data*/public void push(int data){// 如果满的话要进行扩容if (isFull()){this.elem = Arrays.copyOf(this.elem,2*this.elem.length);}this.elem[this.usedSize] = data;this.usedSize++;}/*** 删除栈中的元素【从栈顶开始删除】* @return*/public int pop(){// 栈为空能删除元素吗?if (empty()){System.out.println("当前栈为空!!");return -1;}
//        return this.elem[usedSize--];int oldval = elem[usedSize-1];usedSize--;return oldval;}/*** 判断栈是否为空* @return*/public boolean empty(){if (usedSize == 0){return true;}return false;}/*** 获取栈顶元素,但是不删除栈顶元素* @return*/public int peek(){// 首先要判断一下是否为空if (empty()){System.out.println("当前栈为空!!");return -1;}return elem[usedSize-1];}/*** 获取栈中元素的个数* @return*/public int size(){return usedSize;}/*** 判断一下这个栈有没有满,如果满的话,我们要做一些扩容【扩容的方法要记得】* @return*/public boolean isFull(){return usedSize == elem.length;}}

栈的应用场景

1. 改变元素的序列

大家可以做一下上面两道题,答案分别是C【题型:不可能的出栈顺序】、B

2. 将递归转化为循环

比如:逆序打印链表

// 递归方式
void printList(Node head){if(null != head){printList(head.next);System.out.print(head.val + " ");}
}
// 循环方式
void printList(Node head){if(null == head){return;}Stack<Node> s = new Stack<>();// 将链表中的结点保存在栈中Node cur = head;while(null != cur){s.push(cur);cur = cur.next;}// 将栈中的元素出栈while(!s.empty()){System.out.print(s.pop().val + " ");}
}

3. 括号匹配

20. 有效的括号 - 力扣(LeetCode)

核心要点:字符串遍历完成 && 栈为空 

class Solution {public boolean isValid(String s) {Stack<Character> stack = new Stack<>();  // 实例化一个栈对象for(int i = 0; i < s.length();i++){char ch = s.charAt(i);  // 肯定是括号if(ch == '(' || ch == '{' || ch == '['){//左括号就入栈stack.push(ch);}else{//不是左括号,肯定是右括号了if(stack.empty()){return false;}// 喵一眼栈顶的元素char top = stack.peek();if(ch == '}' && top == '{' || ch == ')' && top == '(' || ch == ']' && top == '['){stack.pop();}else{return false;}}}if(!stack.empty()){return false;}return true;}
}

4. 逆波兰表达式求值

150. 逆波兰表达式求值 - 力扣(LeetCode)

首先我们要了解什么是中缀表达式?什么是后缀表达式?中缀表达式怎么转成后缀表达式?后缀表达式怎么转成中缀表达式?

小编以图解的但是对此 123*+45*6+7*+ 这个后缀表达式用栈的方式进行计算;

如上图所示是利用栈进行后缀表达式计算的所有图示过程。可利用上述进行代码思路的搭建。

方法1:是一种比较低效的方法

class Solution {public int evalRPN(String[] tokens) {Stack<Integer> stack = new Stack<>();for (int i = 0; i < tokens.length; i++) {String token = tokens[i];if (token.equals("/") || token.equals("*") || token.equals("+") || token.equals("-")) {int right = stack.pop();int left = stack.pop();int result = 0;if (token.equals("/")) {result = left / right;} else if (token.equals("*")) {result = left * right;} else if (token.equals("+")) {result = left + right;} else if (token.equals("-")) {result = left - right;}stack.push(result);} else {stack.push(Integer.parseInt(token));}}return stack.pop();}
}

方法2:相比之前的方法,效率有所提高


5. 出栈入栈次序匹配

栈的压入、弹出序列_牛客题霸_牛客网

这个题就是我们在做“不可能的出栈顺序”体型的代码实现。【入栈的同时是可以出栈的!】

上述是小编关于这个题目要求写的 一个图解,希望能够帮助同学们搭建代码的结构。

import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** * @param pushV int整型一维数组 * @param popV int整型一维数组 * @return bool布尔型*/public boolean IsPopOrder (int[] pushV, int[] popV) {Stack<Integer> stack = new Stack<>();int j = 0;for(int i = 0;i < pushV.length;i++){stack.push(pushV[i]);while(!stack.empty()&&stack.peek() == popV[j] && j < popV.length){stack.pop();j++;}}if(stack.empty()){return true;}return false;}
}


6. 最小栈

155. 最小栈 - 力扣(LeetCode)

上述是小编关于这个题目要求写的 一个图解,希望能够帮助同学们搭建代码的结构。【上述两图,图一是入栈,图一是出栈】

代码示例:小编的代码只供参考

class MinStack {private Stack<Integer> stack;private Stack<Integer> minstack;public MinStack() {stack = new Stack<>();minstack = new Stack<>();  //初始化对象}public void push(int val) {stack.push(val);if(minstack.empty()|| minstack.peek() >= val){minstack.push(val);}}public void pop() {int delete = stack.pop();if(!minstack.empty()&& minstack.peek() == delete){minstack.pop();}}// 获取栈顶元素【注意不是删除】public int top() {return stack.peek();}// 获取堆栈中的最小元素【注意不是删除】public int getMin() {return minstack.peek();}
}/*** Your MinStack object will be instantiated and called as such:* MinStack obj = new MinStack();* obj.push(val);* obj.pop();* int param_3 = obj.top();* int param_4 = obj.getMin();*/

概念区分


队列(Queue)

概念

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾(Tail/Rear) 出队列:进行删除操作的一端称为队头(Head/Front.

队列的使用

在Java中,Queue是个接口,底层是通过链表实现的。

下面是关于队列的一些方法:

下面是关于上图中代码的测试:

    /*** 先来一个queue已有方法的测试*/public static void main(String[] args) {Deque<Integer> deque = new LinkedList<>();  // 这是一个双端队列Queue<Integer> queue = new LinkedList<>();  // 这是一个单端队列// 往队列里面放元素queue.offer(11);queue.offer(22);queue.offer(33);System.out.println(queue);System.out.println("========================");// 从队列里面拿元素【先进的先出】(删除)int ret1 = queue.poll();System.out.println(ret1);System.out.println(queue);System.out.println("=========================");// 获取队头元素【这是回去不是删除】int ret2 = queue.peek();System.out.println(ret2);System.out.println(queue);System.out.println("=========================");// 获取队列的长度queue.offer(99);queue.offer(520);queue.offer(1314);System.out.println(queue);  // 先打印一下这个列表int size = queue.size();System.out.println("列表的长度为:" + size);// 检测队列是否为空boolean result1 = queue.isEmpty();System.out.println(result1);queue.poll();queue.poll();queue.poll();queue.poll();queue.poll();boolean result2 = queue.isEmpty();System.out.println(result2);}

如上图所示,在队列里面,其中某一个功能有很多方法可以实现,但是每个方法都有其区别,大家可以私下在查阅资料进行比对。下面是他们的一些适用场景:


队列模拟实现

队列中既然可以存储元素,那底层肯定要有能够保存元素的空间,通过前面线性表的学习了解到常见的空间类型有两种:顺序结构链式结构。同学们思考下:队列的实现使用顺序结构还是链式结构好?

方法实现代码:

package stack_queue;/*** 这个模拟队列的实现基于 双链表 去写*/
public class Myqueue {static class Listnode{public int val;public Listnode next;public Listnode pre;// 再来一个构造方法public Listnode(int val) {this.val = val;}}public Listnode head;  //头节点【队头】public Listnode last; //尾巴节点【队尾】/*** 1.模拟实现往队列里面放元素*/public void offer(int val){Listnode node = new Listnode(val);// 该链表为空【即该队列为空】if (head == null){head = node;last = node;return;}// 如果链表不为空【进行尾插法】last.next = node;node.pre = last;last = node;}/*** 2.模拟实现从队列中取出元素*/public int poll(){// 如果链表为空if (head == null){return -1;}Listnode cur = head;// 如果链表只有一个元素if (head.next == null){head = null;last = null;return cur.val;}// 链表有两个或两个以上的元素head = head.next;head.pre = null;   //把head的前驱置空return cur.val;}/*** 3.获取队头元素*/public int peek(){// 如果链表为空if (head == null){return -1;  // 或者选择抛一个异常【这样更好】}// 如果链表不为空return head.val;}/*** 4.获取队列长度*/public int size(){int usedSize = 0;Listnode cur = head;while (cur != null){usedSize++;cur = cur.next;}return usedSize;}/*** 检测队列是否为空*/public boolean isEmpty(){if (size() == 0){return true;}return false;}/*** 重写toString,为了方便测试的时候看测试结果*/@Overridepublic String toString() {StringBuilder sb = new StringBuilder();sb.append("[");  // 以数组的格式展示Listnode cur = head;while (cur != null) {sb.append(cur.val);if (cur.next != null) {  // 不是最后一个节点,就添加逗号sb.append(", ");}cur = cur.next;}sb.append("]");return sb.toString();}}

测试代码:

/*** 这个是测试模拟队列的实现*/public static void main(String[] args) {Myqueue myqueue = new Myqueue();/*** 1.往队列里面放元素*/myqueue.offer(11);myqueue.offer(22);myqueue.offer(33);myqueue.offer(44);System.out.println(myqueue.toString());System.out.println("======================");/*** 2.从队列中取出元素*/int ret1 = myqueue.poll();System.out.println(myqueue.toString());System.out.println("取出的元素是:"+ret1);System.out.println(myqueue.toString());System.out.println("======================");/*** 3.获取队头元素*/int ret2 = myqueue.peek();System.out.println(myqueue.toString());System.out.println("队头元素是:" + ret2);System.out.println(myqueue.toString());System.out.println("======================");/*** 4.获取队列长度*/System.out.println(myqueue.toString());  // 打印一下列表来验证长度int size = myqueue.size();System.out.println("队列的长度为:" + size);System.out.println("======================");/*** 5.判断队列是否为空*/boolean result1 = myqueue.isEmpty();System.out.println(result1);// 然后把队列中的元素都删除myqueue.poll();myqueue.poll();myqueue.poll();// 再来测试一下boolean result2 = myqueue.isEmpty();System.out.println(result2);System.out.println("=======================");}

注:小编再这里要做一个必要的提醒,小编的代码引导,是其中的一个思路。并不是唯一的实现方法,也不一定是最优的方法。


循环队列

622. 设计循环队列 - 力扣(LeetCode)

提出一个问题:根据前面关于队列的知识,我们在入队的同时,也可以出队。但是对于数组来讲,如果一个数字只能存放10个元素,然后当我们在入队的同时出队,实际上数组还有空位,但是此时按照队列的思路,我们无法往数组里面添加元素了,那数组的存储空间不是白白浪费掉了吗?因此,我们提出了一个循环队列。

实际中我们有时还会使用一种队列叫循环队列。如操作系统课程讲解生产者消费者模型时可以就会使用循环队列。环形队列通常使用数组实现。

那到底什么时候才满呢?提供以下集中思路:

判断是否满了:

1.定义一个usedSize == len;

2.做一个标记;

3.浪费一个空间来区分;

下标的变化:

实现代码示例:

/**
下面这个代码是浪费一个数组空间来实现环形队列的*/
class MyCircularQueue {private int[] elem;    // 创建出一个数组private int front;private int rear;public MyCircularQueue(int k) {// 给这个数组分配一个内存空间this.elem = new int[k+1];   // 分配一个k+1长度的数组空间【因为需要浪费一个空间】}public boolean enQueue(int value) {if(isFull()){return false;}elem[rear] = value;rear = (rear+1)%elem.length;return true;}public boolean deQueue() {if(isEmpty()){return false;}front = (front+1)%elem.length;return true;}public int Front() {if(isEmpty()){return -1;}return elem[front];}// public int Rear() {//     if(isEmpty()){//         return -1;//     }//     return elem[(rear - 1 + elem.length) % elem.length];  // }public int Rear() {if(isEmpty()){return -1;}return elem[(rear - 1 + elem.length) % elem.length]; 
}public boolean isEmpty() {return front == rear;}public boolean isFull() {return (rear + 1) % elem.length == front;}
}/*** Your MyCircularQueue object will be instantiated and called as such:* MyCircularQueue obj = new MyCircularQueue(k);* boolean param_1 = obj.enQueue(value);* boolean param_2 = obj.deQueue();* int param_3 = obj.Front();* int param_4 = obj.Rear();* boolean param_5 = obj.isEmpty();* boolean param_6 = obj.isFull();*/

双端队列 (Deque)

双端队列(deque)是指允许两端都可以进行入队和出队操作的队列,deque 是 “double ended queue” 的简称。那就说明元素可以从队头出队和入队,也可以从队尾出队和入队。

Deque是一个接口,使用时必须创建LinkedList的对象。

在实际工程中,使用Deque接口是比较多的,栈和队列均可以使用该接口。

Deque<Integer> stack = new ArrayDeque<>();//双端队列的线性实现
Deque<Integer> queue = new LinkedList<>();//双端队列的链式实现

在 Java 集合框架(Collection Framework) 中:

  • Deque接口,表示一个双端队列(Double-ended Queue),即可以在头部和尾部插入或删除元素。
  • ArrayDequeLinkedList 都是 Deque 的实现类,提供了两种不同的数据结构方式:
  • Deque<E>(接口)

    • Deque 继承自 Queue 接口,提供 双端插入、删除 功能。
    • 既可以用作队列(FIFO)也可以用作(LIFO)。
  • ArrayDeque<E>(基于数组的双端队列实现)

    • 底层是 可扩容的数组,类似 ArrayList
    • 优点
      • 随机访问快,比 LinkedList 速度更快。
      • 无锁,比 LinkedBlockingDeque 更高效。
    • 缺点
      • 内存占用大,因为需要提前分配数组空间,并且扩容会有一定的开销。
  • LinkedList<E>(基于双向链表的双端队列实现)

    • 底层是 双向链表,类似 LinkedList 结构。
    • 优点
      • 动态扩容,不需要像 ArrayDeque 那样预留数组空间。
      • 插入和删除快,因为不需要移动大量元素(相比 ArrayDeque)。
    • 缺点
      • 访问慢,因为链表结构没有连续内存,访问需要遍历。


面试题

1. 用队列实现栈

225. 用队列实现栈 - 力扣(LeetCode)

思路:

1.当两个队列都为空的时候,说明我模拟实现的栈是空的

2."出栈"的时候,出并不为空的队列,size-1个【size--】.最后那个元素就是我出栈的元素

3."入栈"的时候入到不为空的队列

代码示例:

class MyStack {/**
先创建两个队列*/Queue<Integer> queue1 = null;Queue<Integer> queue2 = null;public MyStack() {queue1 = new LinkedList();queue2 = new LinkedList();}public void push(int x) {if(!queue1.isEmpty()){queue1.offer(x);  // 那个队列不为空就入那个队列}else{queue2.offer(x);}}public int pop() {if (empty()) {return -1;}Queue<Integer> active = queue1.isEmpty() ? queue2 : queue1;Queue<Integer> backup = queue1.isEmpty() ? queue1 : queue2;while (active.size() > 1) {backup.offer(active.poll());}return active.poll();
}public int top() {if (empty()) {return -1;}Queue<Integer> active = queue1.isEmpty() ? queue2 : queue1;Queue<Integer> backup = queue1.isEmpty() ? queue1 : queue2;int res = -1;while (!active.isEmpty()) {res = active.poll();backup.offer(res);}return res;
}public boolean empty() {// 当两个队列都为空的时候,说明我当前模拟实现的栈是空的return (queue1.isEmpty() && queue2.isEmpty());}
}/*** Your MyStack object will be instantiated and called as such:* MyStack obj = new MyStack();* obj.push(x);* int param_2 = obj.pop();* int param_3 = obj.top();* boolean param_4 = obj.empty();*/

2. 用栈实现队列

232. 用栈实现队列 - 力扣(LeetCode)

核心思路:

1.入队的时候,把所有元素全部放在第一个栈中

2.在出队之前要判断一下两个栈空不空,如果两个栈都为空,说明该队列中已经没有元素了。假设栈没有空,判断一下第二个栈中的元素为不为空,如果不为空则出第二个栈中元素;如果为空则把第一个栈中元素全部倒回第二个栈中,然后紧接着出第二个栈的元素。

上述是小编关于这个题目要求写的 一个图解,希望能够帮助同学们搭建代码的结构。

代码示例:

class MyQueue {private Stack<Integer> stack1;private Stack<Integer> stack2;// 进行栈的实例化public MyQueue() {stack1 = new Stack<>();stack2 = new Stack<>();}public void push(int x) {// 往stack1里面放stack1.push(x);}public int pop() {// 首先判断一下队列是否为空if(empty()){return -1;}// 如果队列不为空if(!stack2.empty()){// 如果栈2不为空就从栈2中取出元素return stack2.pop();}else{// 如果栈2为空,则需要把栈2中所有的元素都搬到栈2中来【注意是所有元素】while(!stack1.empty()){stack2.push(stack1.pop());}return stack2.pop();}}// 偷偷瞄一眼但是不删除public int peek() {// 首先判断一下队列是否为空if(empty()){return -1;}// 如果队列不为空if(!stack2.empty()){// 如果栈2不为空就从栈2中取出元素return stack2.peek();}else{// 如果栈2为空,则需要把栈2中所有的元素都搬到栈2中来【注意是所有元素】while(!stack1.empty()){stack2.push(stack1.pop());}return stack2.peek();}}public boolean empty() {// 两个栈为空,队列才为空return (stack1.empty() && stack2.empty());}
}/*** Your MyQueue object will be instantiated and called as such:* MyQueue obj = new MyQueue();* obj.push(x);* int param_2 = obj.pop();* int param_3 = obj.peek();* boolean param_4 = obj.empty();*/

http://www.dtcms.com/wzjs/274689.html

相关文章:

  • frontpage做视频网站北京十大教育培训机构排名
  • 搜狗推广做网站要钱吗域名注册网
  • 献县网站建设公司热门职业培训班
  • 网站设置在设备之间共享怎么开启长沙网络营销公司排名
  • 西安制作网站广告投放运营主要做什么
  • 商城网站建设价格低线上推广活动有哪些
  • 网站制作多少钱方案bt兔子磁力搜索
  • 安徽省建设总站网站十大少儿编程教育品牌
  • 宝山做网站北京债务优化公司
  • 亳州公司做网站个人建站
  • 网站建设198windows优化大师功能
  • 手机网站如何建设网络推广吧
  • 机械加工怎样网上接单想找搜索引擎优化
  • 长春疫情最新消息今天封城了天天seo伪原创工具
  • wep开发和网站开发专门培训seo的网站
  • 网站建设公司官网交换链接营销的典型案例
  • 帮做钓鱼网站会怎样最近新闻摘抄
  • 网站访问过程北京百度seo公司
  • asp.net 手机网站模板国外免费网站域名服务器查询
  • 西宁网站开发多少钱网络推广平台有哪些渠道
  • 大连网站开发师开创集团与百度
  • 山亭建设局网站如何设计网站的首页
  • 学做网站的书哪些好seo性能优化
  • 久久文化传媒有限公司招聘信息抖音seo怎么收费
  • 软件开发与网站建设seo线下培训机构
  • 网站开发题目软文营销写作技巧有哪些?
  • 子目录创建网站石家庄最新消息今天
  • 适合小县城开的加盟店seo网站排名后退
  • 建一个类似淘宝的网站需要多少钱简易网站制作
  • 网站创建流程最近的头条新闻