跟左神学算法_3 基础数据结构(队列和栈)

内容:

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 }

猜你喜欢

转载自www.cnblogs.com/wyb666/p/10159392.html
今日推荐