YAZONG 我的开源

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

 
0 评论0 浏览

一、前提

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

1、1栈/队列基础

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

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

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

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

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

1、2栈的概念

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

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

Screenshot20200105浅析栈与队列在java中的基本应用你可以选择不平凡51CTO博客.png

1、2、1Stack与Vector

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

Screenshot20200105浅析栈与队列在java中的基本应用你可以选择不平凡51CTO博客1.png

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队列的概念

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

Screenshot20200105浅析栈与队列在java中的基本应用你可以选择不平凡51CTO博客2.png

1、3、1Queue

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

Screenshot20200105浅析栈与队列在java中的基本应用你可以选择不平凡51CTO博客3.png

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;
    }
 
}

标题:浅析栈与队列在java中的基本应用
作者:yazong
地址:https://blog.llyweb.com/articles/2016/10/30/1578157243965.html