浅析栈与队列在java中的基本应用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅析栈与队列在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; } }
本文出自 “你可以选择不平凡” 博客,请务必保留此出处http://ylcodes01.blog.51cto.com/5607366/1867337
以上是关于浅析栈与队列在java中的基本应用的主要内容,如果未能解决你的问题,请参考以下文章