内容:
1、数组实现队列和栈
2、返回栈中最小元素
3、对列与栈
4、猫狗队列问题
1、数组实现队列和栈
1 // 用数组实现基本的栈和队列 并在异常时抛出提示信息 2 public class Array_To_Stack_Queue { 3 // 数组实现栈 4 public static class ArrayStack { 5 private Integer[] arr; 6 private Integer index; 7 8 public ArrayStack(int initSize){ 9 // 栈的构造 initSize指定栈大小 10 if(initSize<0){ 11 throw new IllegalArgumentException("The init index is less than 0"); 12 } 13 arr = new Integer[initSize]; 14 index = 0; 15 } 16 17 public Integer peek(){ 18 // 返回栈顶 19 if(index==0){ 20 return null; 21 } 22 return arr[index-1]; 23 } 24 25 public void push(int obj){ 26 // 压数入栈 27 if(index==arr.length){ 28 throw new ArrayIndexOutOfBoundsException("The stack is full!"); 29 } 30 arr[index++] = obj; 31 } 32 33 public Integer pop(){ 34 // 弹出栈顶 35 if(index==0){ 36 throw new ArrayIndexOutOfBoundsException("The stack is empty!"); 37 } 38 return arr[--index]; 39 } 40 41 } 42 43 // 数组实现队列 44 public static class ArrayQueue{ 45 private Integer[] arr; 46 private Integer size; 47 private Integer start; 48 private Integer end; 49 50 public ArrayQueue(int initSize){ 51 if(initSize<0){ 52 throw new IllegalArgumentException("The init size is less than 0"); 53 } 54 arr = new Integer[initSize]; 55 size = 0; 56 start = 0; 57 end = 0; 58 } 59 60 public Integer peek() { 61 // 返回顶部元素 62 if (size == 0) { 63 return null; 64 } 65 return arr[start]; 66 } 67 68 public void push(int obj) { 69 // 向队列中加入元素 70 if (size == arr.length) { 71 throw new ArrayIndexOutOfBoundsException("The queue is full"); 72 } 73 size++; 74 arr[end] = obj; 75 // end如果到最后一个位置就跳回到0 否则+1 76 end = end == arr.length - 1 ? 0 : end + 1; 77 } 78 79 public Integer poll() { 80 // 从队列出取出元素 81 if (size == 0) { 82 throw new ArrayIndexOutOfBoundsException("The queue is empty"); 83 } 84 size--; 85 int tmp = start; 86 // start如果到最后一个位置就跳回到0 否则+1 87 start = start == arr.length - 1 ? 0 : start + 1; 88 return arr[tmp]; 89 } 90 91 } 92 93 }
2、返回栈中最小元素
题目描述:
实现一个特殊的栈 在实现栈的基本功能的基础上 再实现返回栈中最小元素的操作
要求: pop push getMin 操作的时间复杂度都是O(1) 设计的栈类型可以使用现成的栈结构
思路:
使用两个栈,一个data栈用于存放数据,一个min栈用于存放当前压入栈中的数的最小值
每次压栈都把数据压入data栈,如果min栈为空或min栈栈顶大于当前数据就把当前数据压入min栈
代码:
1 public class GetMinStack { 2 public static class MyStack1 { 3 private Stack<Integer> stackData; 4 private Stack<Integer> stackMin; 5 6 public MyStack1() { 7 this.stackData = new Stack<Integer>(); 8 this.stackMin = new Stack<Integer>(); 9 } 10 11 public void push(int newNum) { 12 if (this.stackMin.isEmpty()) { 13 this.stackMin.push(newNum); 14 } else if (newNum < this.getmin()) { 15 this.stackMin.push(newNum); 16 } else { 17 int newMin = this.stackMin.peek(); 18 this.stackMin.push(newMin); 19 } 20 this.stackData.push(newNum); 21 } 22 23 public int pop() { 24 if (this.stackData.isEmpty()) { 25 throw new RuntimeException("Your stack is empty."); 26 } 27 this.stackMin.pop(); 28 return this.stackData.pop(); 29 } 30 31 public int getmin() { 32 if (this.stackMin.isEmpty()) { 33 throw new RuntimeException("Your stack is empty."); 34 } 35 return this.stackMin.peek(); 36 } 37 } 38 39 public static void main(String[] args) { 40 MyStack1 stack1 = new MyStack1(); 41 stack1.push(3); 42 System.out.println(stack1.getmin()); 43 stack1.push(4); 44 System.out.println(stack1.getmin()); 45 stack1.push(1); 46 System.out.println(stack1.getmin()); 47 System.out.println(stack1.pop()); 48 System.out.println(stack1.getmin()); 49 } 50 51 }
3、对列与栈
Java内置队列和栈的使用:
1 import java.util.Stack; 2 import java.util.Queue; 3 import java.util.LinkedList; 4 5 // 使用Java中的内置栈结构和内置队列结构 6 public class useStackAndQueue { 7 8 private static void useStack() { 9 // 使用栈 -> 内容不可为基本数据类型 10 // 内置栈方法如下: 11 // push方法: 向栈中压入元素 12 // peek方法: 返回栈顶元素 13 // pop方法: 从栈顶取出栈顶元素并将其从栈中移除 14 // isEmpty方法: 判断栈是否为空 15 // search方法: 返回对象在栈中位置(-1表示不存在) 16 Stack<Integer> stack = new Stack<Integer>(); 17 stack.push(1); 18 System.out.println(stack.isEmpty()); 19 System.out.println(stack.search(0) + " " + stack.search(1)); 20 System.out.println(stack.peek()); 21 System.out.println(stack.isEmpty()); 22 System.out.println(stack.pop()); 23 System.out.println(stack.isEmpty()); 24 } 25 26 private static void useQueue() { 27 // 使用队列 -> 内容不可为基本数据类型 28 // 内置队列方法如下: 29 // offer方法: 向队列中插入新元素 30 // poll方法: 弹出队列头元素 31 // peek方法: 返回队列头元素 32 // isEmpty方法: 判断队列是否为空 33 // size方法: 计算队列大小 34 Queue<Integer> queue = new LinkedList<Integer>(); 35 System.out.println("The first element is: " + queue.peek()); 36 queue.offer(1); 37 queue.offer(2); 38 queue.offer(3); 39 queue.offer(4); 40 queue.poll(); 41 System.out.println("The first element is: " + queue.peek()); 42 System.out.println("The size is: " + queue.size()); 43 } 44 45 public static void main(String[] args) { 46 System.out.println("use stack: "); 47 useStack(); 48 System.out.println("use queue: "); 49 useQueue(); 50 } 51 52 }
用队列实现栈,用栈实现队列:
思路:两个队列来回倒就可以实现栈,两个栈来回倒也可以实现队列
1 import java.util.LinkedList; 2 import java.util.Queue; 3 import java.util.Stack; 4 5 // 用队列实现栈结构以及用栈结构实现队列结构 6 public class StackAndQueueConvert { 7 public static class TwoStacksQueue{ 8 // 用栈实现队列 9 private Stack<Integer> stackPush; // 入队栈 10 private Stack<Integer> stackPop; // 出队栈 11 12 public TwoStacksQueue(){ 13 stackPush = new Stack<Integer>(); 14 stackPop = new Stack<Integer>(); 15 } 16 17 public void push(int pushInt){ 18 // 入队: 把数据压入入队栈(入队只把数据放进入队栈) 19 stackPush.push(pushInt); 20 } 21 22 public void dao(){ 23 // 倒数据的方法 -> 入队栈倒到出队栈 24 if(!stackPop.isEmpty()){ 25 // 出队栈不为空时不能倒数据 26 return; 27 } 28 while(!stackPush.isEmpty()){ 29 // 只要到数据就要依次倒完 30 stackPop.push(stackPush.pop()); 31 } 32 } 33 34 public int pop(){ 35 // 出队: 取出出队栈栈顶元素(如果出队栈为空入队栈有数据就把入队栈数据压入出队栈) 36 if(stackPop.empty() && stackPush.empty()){ 37 throw new RuntimeException("Queue is empty!"); 38 } 39 dao(); 40 41 return stackPop.pop(); 42 } 43 44 public int peek(){ 45 // 获得顶部元素: 原理和上面的pop一样 只不过最后用的是栈的peek 46 if(stackPop.empty() && stackPush.empty()){ 47 throw new RuntimeException("Queue is empty!"); 48 } 49 dao(); 50 51 return stackPop.peek(); 52 } 53 54 } 55 56 public static class TwoQueuesStack{ 57 // 用队列实现栈 58 private Queue<Integer> data; 59 private Queue<Integer> help; 60 61 public TwoQueuesStack(){ 62 data = new LinkedList<Integer>(); 63 help = new LinkedList<Integer>(); 64 } 65 66 public void push(int pushInt){ 67 // 入栈: 把数据放入data队列中(数只进data队列) 68 data.add(pushInt); 69 } 70 71 public int pop(){ 72 // 出栈: 若data队列不为空把data队列中全部-1个数据出队放到help队列中 73 // 然后data队列中剩下的那个元素就是栈的顶部元素 poll弹出即可 然后交换data队列和help队列 74 if(data.isEmpty()){ 75 throw new RuntimeException("Stack is empty!"); 76 } 77 while(data.size() != 1){ 78 // 把data栈的东西全部拿出依次放入help栈 79 help.add(data.poll()); 80 } 81 int res = data.poll(); 82 swap(); 83 84 return res; 85 } 86 87 public int peek(){ 88 // 获得顶部元素: 若data队列不为空把data队列中全部-1个数据出队放到help队列中 89 // 然后data队列中剩下的那个元素就是栈的顶部元素 用peek取出即可 然后交换data队列和help队列 90 if (data.isEmpty()) { 91 throw new RuntimeException("Stack is empty!"); 92 } 93 while (data.size() != 1) { 94 // 把data栈的东西全部拿出依次放入help栈 95 help.add(data.poll()); 96 } 97 int res = data.peek(); 98 swap(); 99 100 return res; 101 } 102 103 private void swap(){ 104 Queue<Integer> tmp = help; 105 help = data; 106 data = tmp; 107 } 108 109 } 110 }
4、猫狗队列问题
问题描述:
1 代码结构: 2 public class Pet{ 3 private String type; 4 public Pet(String type){ 5 this.type = type; 6 } 7 public String getPetType(){ 8 return this.type; 9 } 10 } 11 public class Dog extends Pet { 12 public Dog(){ 13 super("dog"); 14 } 15 } 16 public class Cat extends Pet{ 17 public Cat(){ 18 super("cat"); 19 } 20 } 21 22 实现一种猫狗队列的结构,要求如下: 23 用户可以调用add方法将cat类或者dog类的实例放入队列中; 24 用户可以调用pollAll方法,将队列中所有的实例按照队列的先后顺序依次弹出; 25 用户可以调用pollDog方法,将队列中dog类的实例按照队列的先后顺序依次弹出; 26 用户可以调用pollCat方法,将队列中cat类的实例按照队列的先后顺序依次弹出; 27 用户可以调用isEmpty方法,检查队列中是否还有dog和cat的实例; 28 用户可以调用isDogEmpty方法,检查队列中是否还有do的实例; 29 用户可以调用isCatEmpty方法,检查队列中是否还有cat的实例。
代码:
1 import java.util.*; 2 3 public class DogCatQueue { 4 public static class Pet { 5 private String type; 6 7 public Pet(String type) { 8 this.type = type; 9 } 10 11 public String getPetType() { 12 return this.type; 13 } 14 } 15 16 public static class Dog extends Pet { 17 public Dog() { 18 super("dog"); 19 } 20 } 21 22 public static class Cat extends Pet { 23 public Cat() { 24 super("cat"); 25 } 26 } 27 28 public static class PetEnterQueue { 29 // 队列中的猫或狗 30 private Pet pet; 31 private long count; 32 33 public PetEnterQueue(Pet pet, long count) { 34 this.pet = pet; 35 this.count = count; 36 } 37 38 public Pet getPet() { 39 return this.pet; 40 } 41 42 public long getCount() { 43 return this.count; 44 } 45 46 } 47 48 public static class dogCatQueue { 49 private Queue<PetEnterQueue> dogQ; 50 private Queue<PetEnterQueue> catQ; 51 private long count; 52 53 public dogCatQueue() { 54 this.dogQ = new LinkedList<DogCatQueue.PetEnterQueue>(); 55 this.catQ = new LinkedList<DogCatQueue.PetEnterQueue>(); 56 this.count = 0; 57 } 58 59 public void add(Pet pet) { 60 // 向队列中添加Cat和Dog的实例 61 if (pet.getPetType().equals("dog")) { 62 this.dogQ.add(new PetEnterQueue(pet, this.count++)); 63 } else if (pet.getPetType().equals("cat")) { 64 this.catQ.add(new PetEnterQueue(pet, this.count++)); 65 } else { 66 throw new RuntimeException("err, not dog or cat"); 67 } 68 } 69 70 public Pet pollAll() { 71 // 猫狗队列中所有的实例按照队列的先后顺序依次弹出 72 if (!this.dogQ.isEmpty() && !this.catQ.isEmpty()) { 73 // count小的是先添加进队列的 74 if (this.dogQ.peek().getCount() < this.catQ.peek().getCount()) { 75 return this.dogQ.poll().getPet(); 76 } else { 77 return this.catQ.poll().getPet(); 78 } 79 } else if (!this.dogQ.isEmpty()) { 80 return this.dogQ.poll().getPet(); 81 } else if (!this.catQ.isEmpty()) { 82 return this.catQ.poll().getPet(); 83 } else { 84 // 猫狗队列都为空 85 throw new RuntimeException("err, queue is empty!"); 86 } 87 } 88 89 public Pet pollDog() { 90 // 将队列中dog类的实例按照队列的先后顺序依次弹出 91 if(this.isDogEmpty()){ 92 throw new RuntimeException("err, dog queue is empty"); 93 } else{ 94 return this.dogQ.poll().getPet(); 95 } 96 } 97 98 public Pet pollCat() { 99 // 将队列中cat类的实例按照队列的先后顺序依次弹出 100 if(this.isCatEmpty()){ 101 throw new RuntimeException("err, cat queue is empty"); 102 } else{ 103 return this.catQ.poll().getPet(); 104 } 105 } 106 107 public boolean isEmpty() { 108 // 检查队列中是否还有dog和cat的实例 109 return this.dogQ.isEmpty() && this.catQ.isEmpty(); 110 } 111 112 public boolean isDogEmpty() { 113 // 检查队列中是否还有dog的实例 114 return this.dogQ.isEmpty(); 115 } 116 117 public boolean isCatEmpty() { 118 // 检查队列中是否还有cat的实例 119 return this.catQ.isEmpty(); 120 } 121 122 } 123 124 public static void main(String[] args) { 125 dogCatQueue test = new dogCatQueue(); 126 127 Pet dog1 = new Dog(); 128 Pet cat1 = new Cat(); 129 Pet dog2 = new Dog(); 130 Pet cat2 = new Cat(); 131 Pet dog3 = new Dog(); 132 Pet cat3 = new Cat(); 133 134 test.add(dog1); 135 test.add(cat1); 136 test.add(dog2); 137 test.add(cat2); 138 test.add(dog3); 139 test.add(cat3); 140 141 test.add(dog1); 142 test.add(cat1); 143 test.add(dog2); 144 test.add(cat2); 145 test.add(dog3); 146 test.add(cat3); 147 148 test.add(dog1); 149 test.add(cat1); 150 test.add(dog2); 151 test.add(cat2); 152 test.add(dog3); 153 test.add(cat3); 154 155 while (!test.isDogEmpty()) { 156 // 弹出所有dog实例 并输出 157 System.out.println(test.pollDog().getPetType()); 158 } 159 160 while (!test.isEmpty()) { 161 // 弹出所有cat实例 并输出 162 System.out.println(test.pollAll().getPetType()); 163 } 164 165 System.out.println(test.isEmpty()); 166 } 167 168 }