浅析栈与队列在java中的基本应用

一、前提

摘自java程序设计教程(华盛顿大学/斯坦福大学著,陈志等译)-机械工业出版社

1、1栈/队列基础

像线性表一样,栈与队列中存储一组有序的值。这类数据结构至少需要支持下面几种操作:

将值放入数据结构中(添加操作);

将值从数据结构中取出(删除操作);

检查数据结构中是否还有值(判断数据结构是否为空)。

栈与队列很相似:都是以某种特定的顺序存储元素序列。栈是一种先进先出/LIFO(LAST IN FIRST OUT)的结构,也就是最后保存到结构中的元素会最先被访问。队列则是一种先进先出/FIFO(FIRST IN FIRST OUT)的结构,也就是最早保存到结构中的元素会最先被访问。

1、2栈的概念

对于栈这种数据结构来说,所有支持的操作都集中在它的一端,我们称为栈的顶部。添加元素的操作成为压栈(push),删除元素的操作称为出栈(pop)。压栈会将新元素保存到栈的顶部,出栈会将栈顶部的元素删除。

举例:我们需要用盘子的时候一般会取最上面的一个,因为如果用下面的盘子,那么会将上面的盘子先挪开。类似的,洗干净的盘子一般直接摞在最上面,而不放在最底下。所以利用栈的这个特性,可以改变元素的顺序。嘴后面加入的元素在出栈时会排在最前面,这样元素的顺序就反转了。

1、2、1Stack与Vector

栈是一种泛型结构,准确的定义为Stack<E>,其中E表示某种数据类型。Stack类是java集合框架中最早的成员之一。在java发布之初就包括stack类,这也导致了stack类在设计方面不如java集合框架中后来加入的抽象数据类,主要体现在没有抽象定义相应的数据类型结构,而是从Vector类扩展而来。Vector类则是ArrayList类的一种早期实现版本。由于存在这种继承关系,可以像处理列表一样处理栈。

1、2、2例子

package org.mbox.test1;
 
import java.util.Stack;
 
public class StackExample {
 
    public static void main(String[] args) {
 
            String str[] = {"aa","bb","cc","dd"};
            Stack<String> stack = new Stack<String>();
            for (int i = 0; i < str.length; i++) {
                stack.push(str[i]);
            }
            System.out.println("栈为:"+stack);
            System.out.println("栈的大小为:"+stack.size());
            System.out.println("删除并返回栈最新顶端的值:"+stack.pop());
            System.out.println("逻辑删除栈顶端的值并返回原栈顶端的值:"+stack.peek());
            
            //以下两个方法的输出是和原数组的顺序是相反的。
            //pop方法删除栈顶端的值并返回最新栈顶端的值
            //顺序打印cc,bb,aa
//          while(!stack.isEmpty()){
//              System.out.println("pop:"+stack.pop()+"  .");
//          }
            
            //peek方法不删除栈顶端的值但返回删除后栈顶端的最新值
            //注意peek元素并不会修改元素
            //一直打印cc是死循环
//          while(!stack.isEmpty()){
//              System.out.println("peek:"+stack.peek()+"   .");
//          }
            
    }
 
}

1、3队列的概念

与栈不同,队列允许在数据结构的两端进行操作:在队列尾部添加数据,从队列头部删除数据。队列支持的操作与栈相同,但名称有区别。队列的添加和删除操作有时也称为入队和出队操作。

1、3、1Queue

Queue<E>定义了队列的抽象数据类型接口和实现。

1、3、2例子

输出结果表明队列中元素存储的顺序就是各个元素加入的顺序。

package org.mbox.test1;
 
import java.util.LinkedList;
import java.util.Queue;
 
public class QueueExample {
 
    public static void main(String[] args) {
 
        String str[]= {"22","33","44","55","66"};
        Queue<String> queue = new LinkedList<String>();
        for(String test:str){
            queue.add(test);
        }
        System.out.println("队列为:"+queue);
        System.out.println("队列大小为:"+queue.size());
        System.out.println("队列逻辑删除首部元素并返回原元素peek:"+queue.peek());
        
//      System.out.print("被删除的队列中的每一个值为:");
//      while(!queue.isEmpty()){
//          System.out.print(queue.remove()+ " ");//返回删除的每个新队列的首部的值
//      }
        //如果要测试下面的方法,记得把上面的打开
        //下面永久打印22的死循环
//      while(!queue.isEmpty()){
//          System.out.println(queue.peek());
//      }
    }
 
}

1、4栈与队列常用操作

1、4、1随机生成栈

package org.mbox.test1;
 
import java.util.Random;
import java.util.Stack;
 
public class StackExample2 {
 
    public static void main(String[] args) {
        Stack<Integer> stack = getRandomStack(10);
        System.out.println("栈为:"+stack);
    }
 
    //生成随机栈
    public static Stack<Integer> getRandomStack(int number){
        Stack<Integer> stack = new Stack<Integer>();
        Random random = new Random();
        for (int i =0; i < number; i++) {
            stack.push(random.nextInt(number));
        }
        return stack;
    }
}

1、4、2随机生成队列

package org.mbox.test1;
 
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
 
public class QueueExample2 {
 
    public static void main(String[] args) {
        Queue<Integer> queue = getRandomQueue(10);
        System.out.println("新队列为:"+queue);
    }
 
    //生成随机的队列
    public static Queue<Integer> getRandomQueue(int number){
        Queue<Integer> queue = new LinkedList<Integer>();
        Random random = new Random();
        for (int i =0; i < 10; i++) {
            queue.add(random.nextInt(number));
        }
        return queue;
    }
}

1、4、3栈与队列互换

package org.mbox.test1;
 
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
import java.util.Stack;
 
public class StackQueueExample {
 
    public static void main(String[] args) {
        Queue<Integer> oldQueue = getRandomQueue(10);
        System.out.println("第一版队列:"+oldQueue);
        Stack<Integer> newStack = getStackOfQueue(oldQueue);
        System.out.println("通过第一版队列生成栈:"+newStack);
        Queue<Integer> newQueue = getQueueOfStack(newStack);
        System.out.println("通过第一版生成的栈生成的队列:"+newQueue);
        
    }
 
    //队列换成栈
    public static Stack<Integer> getStackOfQueue(Queue<Integer> queue){
        Stack<Integer> stack = new Stack<Integer>();
        while(!queue.isEmpty()){
            int n =queue.remove();//注意这里是remove方法
            stack.push(n);//注意这里是push压栈方法,而不是add方法,注意两个方法的区别
        }
        
        return stack;
    }
    
    //栈换成队列
    public static Queue<Integer> getQueueOfStack(Stack<Integer> stack){
        Queue<Integer> queue = new LinkedList<Integer>();
        while(!stack.isEmpty()){
            int n =stack.pop();//注意这里是pop方法而不是peek方法
            queue.add(n);//注意这里是add方法
        }
        return queue;
    }
    
    
    //生成随机的队列
    public static Queue<Integer> getRandomQueue(int number){
        Queue<Integer> queue = new LinkedList<Integer>();
        Random random = new Random();
        for (int i =0; i < 10; i++) {
            queue.add(random.nextInt(number));
        }
        return queue;
    }
    
    //生成随机栈
    public static Stack<Integer> getRandomStack(int number){
        Stack<Integer> stack = new Stack<Integer>();
        Random random = new Random();
        for (int i =0; i < number; i++) {
            stack.push(random.nextInt(number));
        }
        return stack;
    }   
        
}

1、4、4队列求和(注意和栈求和的区别)

package org.mbox.test1;
 
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
 
public class QueueExample3 {
 
    public static void main(String[] args) {
        Queue<Integer> queue = getRandomQueue(10);
        System.out.println("执行前queue:"+queue);
        System.out.println("相加结果:"+sum(queue));
        System.out.println("执行后queue:"+queue);
    }
 
    //生成随机的队列
    public static Queue<Integer> getRandomQueue(int number){
        Queue<Integer> queue = new LinkedList<Integer>();
        Random random= new Random();
        for (int i =0; i < 10; i++) {
            queue.add(random.nextInt(number));
        }
        return queue;
    }
 
    //队列求和
    public static int sum(Queue<Integer> queue){
        int sum = 0;
        
        //1
//      //用while循环改变了原队列的内容是不可取的
        //但是可以使用一个新的队列进行处理
//      Queue<Integer> queue2 = new LinkedList<Integer>();
        while(!queue.isEmpty()){
            int n =queue.remove();
            sum +=n;
//          queue2.add(n);
        }
//      System.out.println(queue2);
        
        //2
//      for (int i =0; i < queue.size(); i++) {
////            System.out.println(i);
//          int n = queue.remove();
//          sum +=n;
//          //注意在使用下述原队列进行处理的时候,
//          //如果不执行add操作,那么sum只会加了前五个值,因为remove的同时这个队列的值的个数也是随之减少的
//          queue.add(n);
//          //队列的定义是从首部删除,尾部进入
//          //虽然新元素进入了队列,但是还是从首部一个个删除的,此时队列的长度是保持不变的
//          //所以等删除到最后一个元素的时候,新加入的10个元素还是以前的10个元素,是不会变的,此时for循环也结束了。
//      }
        
        return sum;
    }
}

1、4、5栈求和(注意和队列求和的区别)

package org.mbox.test1;
 
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
import java.util.Stack;
 
public class StackExample3 {
 
    
    public static void main(String[] args) {
        Stack<Integer> stack = getRandomStack(10);
        System.out.println("执行前栈为:"+stack);
        System.out.println("求和结果为:"+sum(stack));
        System.out.println("执行后栈为:"+stack);
    }
 
    //生成随机栈
    public static Stack<Integer> getRandomStack(int number){
        Stack<Integer> stack = new Stack<Integer>();
        Random random = new Random();
        for (int i =0; i < number; i++) {
            stack.push(random.nextInt(number));
        }
        return stack;
    }
    //栈求和
    public static int sum(Stack<Integer> stack){
        int sum = 0;
        
//      //1方案
//      //下述操作是不可行的,栈是后进先出原则
//      //下列操作相当于把最后一个元素加了10次
//      //看起来生成的最终结果跟原结果相同,但是是不对的
//      for (int i =0; i < stack.size(); i++) {
//          int n =stack.pop();//拿出来尾部元素
//          sum +=n;
//          stack.push(n);//把拿出来的尾部元素再放回原位置
//      }
        
//      //2
//      //下述操作只把最后五个数相加了
//      for (int i =0; i < stack.size(); i++) {
//          System.out.println(i);
//          int n =stack.pop();
//          sum +=n;
//      }
        
        //3
        Queue<Integer> queue = new LinkedList<Integer>();
        while(!stack.isEmpty()){
            int n =stack.pop();
            sum +=n;
            queue.add(n);
        }
        System.out.println(queue);
        System.out.println(getStackOfQueue(queue,stack));
        System.out.println(getQueueOfStack(stack,queue));
        System.out.println(getStackOfQueue(queue,stack));
        return sum;
    }
    
    //队列换成栈
    public static Stack<Integer> getStackOfQueue(Queue<Integer>queue,Stack<Integer> stack){
        while(!queue.isEmpty()){
            int n =queue.remove();//注意这里是remove方法
            stack.push(n);//注意这里是push压栈方法,而不是add方法,注意两个方法的区别
        }
        
        return stack;
    }
    //栈换成队列
    public static Queue<Integer> getQueueOfStack(Stack<Integer>stack,Queue<Integer> queue){
        while(!stack.isEmpty()){
            int n =stack.pop();//注意这里是pop方法而不是peek方法
            queue.add(n);//注意这里是add方法
        }
        return queue;
    }   
}

1、5栈和队列高级操作

1、5、1删除队列中指定的元素

package org.mbox.test1;
 
import java.util.LinkedList;
import java.util.Queue;
 
public class QueueExample4 {
 
    public static void main(String[] args) {
        Queue<Integer> queue = getQueue();
        System.out.println(""+ queue);
        System.out.println(getNewQueue(queue,5));
    }
 
    public static Queue<Integer>getQueue(){
        Queue<Integer> queue = new LinkedList<Integer>();
        queue.add(5);
        queue.add(5);
        queue.add(2);
        queue.add(51);
        queue.add(5);
        queue.add(3);
        queue.add(5);
        queue.add(6);
        return queue;
    }
        
    public static Queue<Integer> getNewQueue(Queue<Integer> queue,int number){
        int oldSize= queue.size();//这里一定要先获取到原队列的长度,不然会造成数据错误
        for (int i =0; i < oldSize; i++) {
            int n =queue.remove();
            if(n !=number){
                queue.add(n);
            }
        }
        
        return queue;
    }
}

1、5、2比较两个栈奇偶是否一样

package org.mbox.test1;
 
import java.util.Stack;
 
public class StackExample4 {
 
    public static void main(String[] args) {
        Integer array1[] = {1,2,3,4,5,6,7};
        Integer array2[] = {11,12,13,15,15,16,17};
        Stack<Integer> stack1 = getStack(array1);
        Stack<Integer> stack2 = getStack(array2);
        
        System.out.println("stack1:"+stack1);
        System.out.println("stack2:"+stack2);
        
        System.out.println(checkStack(stack1,stack2));
    }
    
    public static boolean checkStack(Stack<Integer> stack1,Stack<Integer> stack2){
        
        System.out.println("1--------------------stack1:"+stack1);
        System.out.println("1--------------------stack2:"+stack2);
        
        if(stack1.size()!= stack2.size()){
            returnfalse;
        }else{
            boolean flag = true;
            Stack<Integer> stack3 = new Stack<Integer>();
            while(flag&& !stack1.isEmpty() && !stack2.isEmpty()){
                intn1 = stack1.pop();
                intn2 = stack2.pop();
                if((n1% 2) != (n2 % 2)){
                    flag= false;
                }
                stack3.push(n1);
                stack3.push(n2);
            }
            System.out.println("2--------------------stack1:"+stack1);
            System.out.println("2--------------------stack2:"+stack2);
            System.out.println("2--------------------stack3:"+stack3);
            while(!stack3.isEmpty()){
                stack2.push(stack3.pop());
                stack1.push(stack3.pop());
            }
            System.out.println("3--------------------stack1:"+stack1);
            System.out.println("3--------------------stack2:"+stack2);
            System.out.println("3--------------------stack3:"+stack3);
            return flag;
        }
        
    }
    
    public static Stack<Integer> getStack(Integer array[]){
        Stack<Integer> stack = new Stack<Integer>();
        for(Integer num : array){
            stack.push(num);
        }
        return stack;
    }
 
}
时间: 2024-08-04 22:33:32

浅析栈与队列在java中的基本应用的相关文章

栈和队列的Java实现

一.  栈 1.概念 栈是一种特殊的线性表,它只能在栈顶(top)进行插入(push)和删除(pop)操作. 栈的常用操作: 入栈(push):向栈顶插入元素 出栈(pop):从栈顶删除元素 访问栈顶元素(peek):访问栈顶元素 2. 栈的顺序结构的实现 1 public class SequenceStack<T> { 2 3 private Object[] elementData; //数组用于承装元素 4 private int DEFAULT_SIZE = 20; //初始数组默认

数据结构之栈和队列及其Java实现

栈和队列是数据结构中非常常见又非常基础的线性表,在某些场合栈和队列使用很多,因此本篇主要介绍栈和队列,并用Java实现基本的栈和队列,同时用两个栈实现队列和用两个队列实现栈. 栈:栈是一种基于"后进先出"策略的线性表.在插入时(入栈),最先插入的元素在栈尾,最后插入的元素在栈顶:在删除时(出栈),最后插入的元素先出栈,最先插入的元素最后出栈.由此可见,对栈的插入和删除操作都是在栈顶位置进行的. 在Java中,提供了一个类Stack<E>来实现栈的这些特性,并提供了一些常用的

算法_栈与队列的Java链表实现

链表是一个递归的数据结构,它或者为null,或者是指向一个结点的引用,该结点含有一个泛型的元素和指向另一个链表的引用.可以用一个内部类来定义节点的抽象数据类型: private class Node /*定义节点类*/{ Item item; Node next; } 根据递归的定义,我们只需一个Node类型的变量就能表示一条链表,只要保证它的值是null或者指向另一个Node对象,且该对象的next域指向了另一条链表即可.链表表示的是一列元素,虽然也可以用数组来表示一列元素,但是在链表中插入元

栈和队列的java简单实现

栈:这是一个先进后出的数据结构,生活中类似的浏览器的返回上一页就可以利用此结构实现,代码如下: public class Stack<T> { private Object[] data;//存储数据 private int top;//表示栈顶元素 public Stack(){ data = new Object[100];//为了说明原理随意指定 top =-1; } public synchronized void put(T t){ //压栈 data[data.length] =

剑指Offer-5.用两个栈实现队列(C++/Java)

题目: 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 分析: 栈的特点是先进后出,队列的特点则是先进先出. 题目要求我们用两个栈来实现一个队列,栈和队列都有入栈(入队)的操作,所以我们可以使用一个栈来模拟入队的操作,另一个栈用来负责出队. 利用stack1模拟入队操作,stack2模拟出队操作. 当有元素入队时,就直接压入stack1中,当要出出队时,stack1中元素弹出的顺序和要求出队的顺序是正好相反的,我们可以将stack1的元素依次弹出,再压入st

剑指offer-面试题7:俩个栈实现队列(java)

详细分析请参照C语言版,这里仅仅给出实现代码,注释很详细,不得不说java各种api用起来真是爽飞了 1 package com.xsf.SordForOffer; 2 3 import java.util.Stack; 4 5 /** 6 * 剑指offer pro7,俩个链表实现一个队列 7 * @author ELVIS 8 */ 9 class ListQueue{ 10 //定义俩个栈 11 private Stack<String> stack1 = new Stack<St

(基础篇)浅析JAVA中的栈和堆

若为生活所迫,做了自己不喜欢做的事.却没有达到自己预期想要的结果,那么何必强迫自己,苦恼这一世.不如转而做自己喜欢的事,哪怕像我一样从头开始. 一.概念 [老生常谈]对于刚接触计算机,没几年的我来说,好多老生常谈的概念对我而言都很新鲜.下面的概念也不例外.他们说对学计算机的而言,堆栈是一个不容忽视的概念. 1.堆栈是两种数据结构,只能在一端对数据项进行插入和删除. 2.在单片机应用中,堆栈是个特殊的存储区,主要是暂时存放数据和地址. 3.堆,队列优先,先进先出 4.栈,先进后出 [java中堆栈

JavaScript数组模拟栈和队列

*栈和队列:js中没有真正的栈和队列的类型              一切都是用数组对象模拟的 栈:只能从一端进出的数组,另一端封闭       FILO   何时使用:今后只要仅希望数组只能从一端进出时   如何使用:2种情况:     1. 末尾出入栈:已入栈元素的下标不再改变        入栈: arr.push(新值1,...)        出站: var last=arr.pop() 2. 开头出入栈:每次入栈新元素时,已入栈元素的位置都会向后顺移.        入栈:arr.u

栈、队列、堆

新年伊始 再破一谜团 区别参考: 队列只能在队头做删除操作,在队尾做插入操作.而栈只能在栈顶做插入和删除操作栈就是一个桶,后放进去的先拿出来,它下面本来有的东西要等它出来之后才能出来堆是在程序运行时,而不是在程序编译时,申请某个大小的内存空间.即动态分配内存,对其访问和对一般内存的访问没有区别. {堆是指程序运行是申请的动态内存,而栈只是指一种使用堆的方法(即先进后出).} 栈是先进后出的,但是于堆而言却没有这个特性,两者都是存放临时数据的地方. 对于堆,我们可以随心所欲的进行增加变量和删除变量