提示:关于栈和队列的实现着实很简朴,根本上是对之前的次序表和链表的一种应用,代码部分也不难。重要的是对栈和队列的实际运用。
一、什么是栈?
可以明白为一个竖过来的数组、次序表,同时这个数组只能将末端的元素先推出来,再推出来前面的元素,也就是我们所说的,先辈后出、后进先出。
栈的实例化
- Stack<E> stack = new Stack<>();
复制代码 1.1 栈的模仿实现
自界说的接口,规范自界说的类,便于模仿实现
- public interface IStack {
- //放入元素
- int push(int a);
- //推出栈顶元素
- int pop();
- //查看栈顶元素
- int peek();
- //栈是否为空
- boolean isEmpty(int[] array);
- //栈中的元素个数
- int size();
- //栈中寻找某个元素距离栈顶的距离
- int search(int a);
- }
复制代码 push(int a) — 将元素放入栈中
- public int push(int a) {
- isFull(array);
- array[useSide++] = a;
- return a;
- }
复制代码
peek() — 检察栈顶元素
- public int peek() {
- try {
- if(isEmpty(array)){
- throw new EmptyException("空数组读取异常");
- }
- }catch (EmptyException e){
- e.printStackTrace();
- }
- return array[useSide - 1];
- }
复制代码
pop() — 出栈顶元素
- public int pop() {
- int top = peek();
- useSide--;
- return top;
- }
复制代码
isEmpty(int[] array) — 判定栈是否为空
- public boolean isEmpty(int[] array) {
- return array.length == useSide;
- }
复制代码 size() — 得到栈中的元素个数
- public int size() {
- return useSide;
- }
复制代码 search(int a) — 得到栈中某个元素隔断栈顶的隔断,栈顶元素位置按1来盘算
- public int search(int a) {
- int cur = useSide - 1;
- int len = 1;
- while (0 <= cur){
- if(a == array[cur]){
- return len;
- }else {
- cur--;
- len++;
- }
- }
- return -1;
- }
复制代码 代码整合
- public class MyStack implements IStack{ private int[] array; public MyStack() { this.array = new int[10]; } private int useSide; private void isFull(int[] check){ if(isEmpty(check)){ array = Arrays.copyOf(check,2*check.length); } } @Override public int push(int a) {
- isFull(array);
- array[useSide++] = a;
- return a;
- }
- @Override public int pop() {
- int top = peek();
- useSide--;
- return top;
- }
- @Override public int peek() {
- try {
- if(isEmpty(array)){
- throw new EmptyException("空数组读取异常");
- }
- }catch (EmptyException e){
- e.printStackTrace();
- }
- return array[useSide - 1];
- }
- @Override public boolean isEmpty(int[] array) {
- return array.length == useSide;
- }
- @Override public int size() {
- return useSide;
- }
- @Override public int search(int a) {
- int cur = useSide - 1;
- int len = 1;
- while (0 <= cur){
- if(a == array[cur]){
- return len;
- }else {
- cur--;
- len++;
- }
- }
- return -1;
- }
- }
复制代码 1.2 关于栈的例题
例题1 有效括号
- class Solution {
- public boolean isValid(String s) {
- Stack<Character> stack = new Stack<>();
- if(s == null){
- return false;
- }
- for(int i = 0; i < s.length(); i++){
- char cur = s.charAt(i);
- if(cur == '(' || cur == '{' || cur == '['){
- stack.push(cur);
- }else if(cur == ')' || cur == '}' || cur == ']'){
- if(stack.isEmpty()){
- return false;
- }
- if(cur == ')'&&stack.peek() == '(' ||
- cur == '}'&&stack.peek() == '{' ||
- cur == ']'&&stack.peek() == '['){
- stack.pop();
- }else{
- return false;
- }
- }else{
- return false;
- }
- }
- if(stack.isEmpty()){
- return true;
- }
- return false;
- }
- }
复制代码 例题2 逆波兰表达式

- public int evalRPN(String[] tokens) {
-
- Stack<String> stack = new Stack<>();
- for(int i = 0; i < tokens.length; i++){
- if(tokens[i].equals("+") || tokens[i].equals("-") || tokens[i].equals("*") || tokens[i].equals("/")){
- int m = Integer.parseInt(stack.pop());
- int n = Integer.parseInt(stack.pop());
- if(tokens[i].equals("+")){
- stack.push(String.valueOf(m+n));
- }else if(tokens[i].equals("-")){
- stack.push(String.valueOf(n-m));
- }else if(tokens[i].equals("*")){
- stack.push(String.valueOf(m*n));
- }else{
- stack.push(String.valueOf(n/m));
- }
- }else{
- stack.push(tokens[i]);
- }
- }
- return Integer.parseInt(stack.pop());
- }
复制代码 例题3 最小栈

- public Stack<Integer> stack;
- public Stack<Integer> minStack;
- public MinStack() {
- stack = new Stack<>();
- minStack = new Stack<>();
- }
-
- public void push(int val) {
- stack.push(val);
- if(minStack.empty()){
- minStack.push(val);
- }else{
- int m = minStack.peek();
- if(m >= val){
- minStack.push(val);
- }
- }
- }
-
- public void pop() {
- if(stack.empty()){
- return;
- }
- int m = stack.pop();
- if(m == minStack.peek()){
- minStack.pop();
- }
- }
-
- public int top() {
- if(stack.empty()){
- return -1;
- }
- return stack.peek();
- }
-
- public int getMin() {
- if(minStack.empty()){
- return -1;
- }
- return minStack.peek();
- }
复制代码 例题4 栈的压入、弹出序列
- public boolean IsPopOrder (int[] pushV, int[] popV) {
- // write code here
- Stack<Integer> stack = new Stack<>();
- int j = 0;
- for(int i = 0; i < pushV.length;i++){
- stack.push(pushV[i]);
- while(!stack.isEmpty() && stack.peek() == popV[j] && j < popV.length){
- stack.pop();
- j++;
- }
- }
-
- return stack.isEmpty();
- }
复制代码 二、什么是队列?
可以明白为一个双向链表(一个一个节点在列队),同时这个链表只能将队头的元素先推出来,再推出来反面的元素,也就是我们所说的,先辈先出、后进后出。
队列的实例化
- Deque<E> stack = new ArrayDeque<>();//双端队列的线性实现
- Deque<E> queue = new LinkedList<>();//双端队列的链式实现
复制代码 2.2 队列的模仿实现
自界说的接口,规范自界说的类,便于模仿实现
- public interface IQueue {
- //
- int offer(int a);
- int poll();
- int peek();
- boolean isEmpty();
- }
复制代码 isEmpty() — 判定是否为空队列
- @Override
- public boolean isEmpty() {
- return useSide == 0;
- }
复制代码 offer(int a) — 从队尾放入元素
- public int offer(int a) {
- ListNode listNode = new ListNode(a);
- listNode.val = a;
- if(isEmpty()){
- head = listNode;
- last = listNode;
- }else {
- last.next = listNode;
- listNode.pre = last;
- last = listNode;
- }
- useSide++;
- return a;
- }
复制代码
peek() — 检察队头元素
- public int peek() {
- try {
- if(head == null){
- throw new EmptyException("空指针异常访问");
- }
- }catch (EmptyException e){
- e.printStackTrace();
- }
- return head.val;
- }
复制代码
poll() — 推出队头的元素
- public int poll() {
- int fisrt = peek();
- head = head.next;
- useSide --;
- return fisrt;
- }
复制代码
代码整合
- public class MyQueue implements IQueue{ static class ListNode{ int val; ListNode pre; ListNode next; public ListNode(int val) { this.val = val; } } private ListNode head; private ListNode last; private int useSide; @Override public int offer(int a) {
- ListNode listNode = new ListNode(a);
- listNode.val = a;
- if(isEmpty()){
- head = listNode;
- last = listNode;
- }else {
- last.next = listNode;
- listNode.pre = last;
- last = listNode;
- }
- useSide++;
- return a;
- }
- @Override public int poll() {
- int fisrt = peek();
- head = head.next;
- useSide --;
- return fisrt;
- }
- @Override public int peek() {
- try {
- if(head == null){
- throw new EmptyException("空指针异常访问");
- }
- }catch (EmptyException e){
- e.printStackTrace();
- }
- return head.val;
- }
- @Override
- public boolean isEmpty() {
- return useSide == 0;
- }
- }
复制代码 2.2 关于队列的例题
例题1 筹划循环队列
- class MyCircularQueue {
- public int[] array;
- int front;
- int rear;
- public MyCircularQueue(int k) {
- array = new int[k+1];
- }
- // 向循环队列插入一个元素。如果成功插入则返回真。
- public boolean enQueue(int value) {
- if(isFull()){
- return false;
- }
- array[rear] = value;
- rear = (rear+1) % array.length;
- return true;
- }
- //从循环队列中删除一个元素。如果成功删除则返回真。
- public boolean deQueue() {
- if(isEmpty()){
- return false;
- }
- front = (front+1) % array.length;
- return true;
- }
- //从队首获取元素。如果队列为空,返回 -1 。
- public int Front() {
- if(isEmpty()){
- return -1;
- }
- return array[front];
- }
- //获取队尾元素。如果队列为空,返回 -1 。
- public int Rear() {
- if(isEmpty()){
- return -1;
- }
- if(rear == 0){
- return array[array.length - 1];
- }
- return array[rear-1];
- }
- //检查循环队列是否为空。
- public boolean isEmpty() {
- return rear == front;
- }
- //检查循环队列是否已满。
- public boolean isFull() {
- return (rear+1) % array.length == front;
- }
- }
复制代码 例题2 用队列实现栈

- class MyStack {
- public Queue<Integer> queue1;
- public Queue<Integer> queue2;
- int size;
- public MyStack() {
- queue1 = new LinkedList<>();
- queue2 = new LinkedList<>();
- }
-
- public void push(int x) {
- if(queue1.isEmpty() && queue2.isEmpty()){
- queue1.offer(x);
- size++;
- }else if(!queue1.isEmpty()){
- queue1.offer(x);
- size++;
- }else if(!queue2.isEmpty()){
- queue2.offer(x);
- size++;
- }
- }
-
- public int pop() {
- if(queue1.isEmpty() && queue2.isEmpty()){
- return -1;
- }
- if(queue1.isEmpty() && !queue2.isEmpty()){
- int cur = size - 1;
- while(cur != 0){
- queue1.offer(queue2.poll());
- cur--;
- }
- size--;
- return queue2.poll();
- }else if(!queue1.isEmpty() && queue2.isEmpty()){
- int cur = size - 1;
- while(cur != 0){
- queue2.offer(queue1.poll());
- cur--;
- }
- size--;
- return queue1.poll();
- }
- return -1;
- }
-
- public int top() {
- if(queue1.isEmpty() && queue2.isEmpty()){
- return -1;
- }
- if(queue1.isEmpty() && !queue2.isEmpty()){
- int cur = size - 1;
- while(cur != 0){
- queue1.offer(queue2.poll());
- cur--;
- }
- int m = queue2.peek();
- queue1.offer(queue2.poll());
- return m;
- }else if(!queue1.isEmpty() && queue2.isEmpty()){
- int cur = size - 1;
- while(cur != 0){
- queue2.offer(queue1.poll());
- cur--;
- }
- int m = queue1.peek();
- queue2.offer(queue1.poll());
- return m;
- }
- return -1;
- }
-
- public boolean empty() {
- return size == 0;
- }
- }
复制代码 例题3 用栈实现队列

- Stack<Integer> stack1;
- Stack<Integer> stack2;
- int size = 0;
- public MyQueue() {
- stack1 = new Stack<>();
- stack2 = new Stack<>();
- }
- //将元素 x 推到队列的末尾
- public void push(int x) {
- stack1.push(x);
- size++;
- }
- //从队列的开头移除并返回元素
- public int pop() {
- if(empty()){
- return -1;
- }
- if(!stack2.isEmpty()){
- size--;
- return stack2.pop();
- }else if(stack2.isEmpty() && !stack1.isEmpty()){
- while(!stack1.isEmpty()){
- stack2.push(stack1.pop());
- }
- size--;
- return stack2.pop();
- }
- return -1;
- }
- //返回队列开头的元素
- public int peek() {
- if(empty()){
- return -1;
- }
- if(!stack2.isEmpty()){
- return stack2.peek();
- }else if(stack2.isEmpty() && !stack1.isEmpty()){
- while(!stack1.isEmpty()){
- stack2.push(stack1.pop());
- }
- return stack2.peek();
- }
- return -1;
- }
- //如果队列为空,返回 true ;否则,返回 false
- public boolean empty() {
- return size == 0;
- }
复制代码 总结
本篇文章先容了有关数据布局中的栈和队列的相干内容,以及它们的简质朴现,和简朴利用,如果有什么不准确的大概不严谨的地方,还望指正,谢谢各人!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金 |