目录
  1. 1. 一、简介
  2. 2. 二、代码
    1. 2.1. 1接口
    2. 2.2. 2 ArrayStack(基于动态数组)
    3. 2.3. 3 LinkedListStack
    4. 2.4. 4 比较两种实现

一、简介

  • 后进先出,从栈顶进栈顶出

  • 应用

    image-20200312153907702

二、代码

1接口

1
2
3
4
5
6
7
8
public interface Stack<E> {

int getSize();//栈一共有多少元素
boolean isEmpty();?//栈是否为空
void push(E e);//添加元素/入栈
E pop();//出栈
E peek();//查看栈顶元素
}

2 ArrayStack(基于动态数组)

  • 数组尾部是栈顶,添加删除都是在栈顶进行
  • 时间复杂度
    • 时间复杂度都是01(添加删除操作存在resize但是考虑均摊时间复杂度也是O1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
public class ArrayStack<E> implements Stack<E> {

private Array<E> array;
//capacity 栈容积,数组规模
public ArrayStack(int capacity){
array = new Array<>(capacity);
}
//使用数组默认的10
public ArrayStack(){
array = new Array<>();
}

@Override
public int getSize(){
return array.getSize();
}

@Override
public boolean isEmpty(){
return array.isEmpty();
}

public int getCapacity(){
return array.getCapacity();
}

@Override
public void push(E e){
array.addLast(e);
}

@Override
public E pop(){
return array.removeLast();
}

@Override
public E peek(){
return array.getLast();
}

@Override
public String toString(){
StringBuilder res = new StringBuilder();
res.append("Stack: ");
res.append('[');
for(int i = 0 ; i < array.getSize() ; i ++){
res.append(array.get(i));
if(i != array.getSize() - 1)
res.append(", ");
}
res.append("] top");
return res.toString();
}
}


//动态数组
public class Array<E> {

private E[] data;
//size指数组实际长度,capacity指为数组开辟的最大长度
private int size;

// 构造函数,传入数组的容量capacity构造Array
public Array(int capacity){
data = (E[])new Object[capacity];
size = 0;
}

// 无参数的构造函数,默认数组的容量capacity=10
public Array(){
this(10);
}

// 获取数组的容量
public int getCapacity(){
return data.length;
}

// 获取数组中的元素个数
public int getSize(){
return size;
}

// 返回数组是否为空
public boolean isEmpty(){
return size == 0;
}

// 在index索引的位置插入一个新元素e
public void add(int index, E e){

if(index < 0 || index > size)
throw new IllegalArgumentException("Add failed. Require index >= 0 and index <= size.");

if(size == data.length)
resize(2 * data.length);

for(int i = size - 1; i >= index ; i --)
data[i + 1] = data[i];

data[index] = e;

size ++;
}

// 向所有元素后添加一个新元素
public void addLast(E e){
add(size, e);
}

// 在所有元素前添加一个新元素
public void addFirst(E e){
add(0, e);
}

// 获取index索引位置的元素
public E get(int index){
if(index < 0 || index >= size)
throw new IllegalArgumentException("Get failed. Index is illegal.");
return data[index];
}

public E getLast(){
return get(size - 1);
}

public E getFirst(){
return get(0);
}

// 修改index索引位置的元素为e
public void set(int index, E e){
if(index < 0 || index >= size)
throw new IllegalArgumentException("Set failed. Index is illegal.");
data[index] = e;
}

// 查找数组中是否有元素e
public boolean contains(E e){
for(int i = 0 ; i < size ; i ++){
if(data[i].equals(e))
return true;
}
return false;
}

// 查找数组中元素e所在的索引,如果不存在元素e,则返回-1
public int find(E e){
for(int i = 0 ; i < size ; i ++){
if(data[i].equals(e))
return i;
}
return -1;
}

// 从数组中删除index位置的元素, 返回删除的元素
public E remove(int index){
if(index < 0 || index >= size)
throw new IllegalArgumentException("Remove failed. Index is illegal.");

E ret = data[index];
for(int i = index + 1 ; i < size ; i ++)
data[i - 1] = data[i];
size --;
data[size] = null; // loitering objects != memory leak

if(size == data.length / 4 && data.length / 2 != 0)
resize(data.length / 2);
return ret;
}

// 从数组中删除第一个元素, 返回删除的元素
public E removeFirst(){
return remove(0);
}

// 从数组中删除最后一个元素, 返回删除的元素
public E removeLast(){
return remove(size - 1);
}

// 从数组中删除元素e
public void removeElement(E e){
int index = find(e);
if(index != -1)
remove(index);
}

@Override
public String toString(){

StringBuilder res = new StringBuilder();
res.append(String.format("Array: size = %d , capacity = %d\n", size, data.length));
res.append('[');
for(int i = 0 ; i < size ; i ++){
res.append(data[i]);
if(i != size - 1)
res.append(", ");
}
res.append(']');
return res.toString();
}

// 将数组空间的容量变成newCapacity大小
private void resize(int newCapacity){

E[] newData = (E[])new Object[newCapacity];
for(int i = 0 ; i < size ; i ++)
newData[i] = data[i];
data = newData;
}
}

3 LinkedListStack

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class LinkedListStack<E> implements Stack<E> {

private LinkedList<E> list;

public LinkedListStack(){
list = new LinkedList<>();
}

@Override
public int getSize(){
return list.getSize();
}

@Override
public boolean isEmpty(){
return list.isEmpty();
}

@Override
public void push(E e){
list.addFirst(e);
}

@Override
public E pop(){
return list.removeFirst();
}

@Override
public E peek(){
return list.getFirst();
}

@Override
public String toString(){
StringBuilder res = new StringBuilder();
res.append("Stack: top ");
res.append(list);
return res.toString();
}

public static void main(String[] args) {

LinkedListStack<Integer> stack = new LinkedListStack<>();

for(int i = 0 ; i < 5 ; i ++){
stack.push(i);
System.out.println(stack);
}

stack.pop();
System.out.println(stack);
}
}

4 比较两种实现

  • 两者时间复杂度相同,运行速度主要受JVM等其他因素影响
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class Main {

// 测试使用stack运行opCount个push和pop操作所需要的时间,单位:秒
private static double testStack(Stack<Integer> stack, int opCount){

long startTime = System.nanoTime();

Random random = new Random();
for(int i = 0 ; i < opCount ; i ++)
stack.push(random.nextInt(Integer.MAX_VALUE));
for(int i = 0 ; i < opCount ; i ++)
stack.pop();

long endTime = System.nanoTime();

return (endTime - startTime) / 1000000000.0;
}

public static void main(String[] args) {

int opCount = 100000;

ArrayStack<Integer> arrayStack = new ArrayStack<>();
double time1 = testStack(arrayStack, opCount);
System.out.println("ArrayStack, time: " + time1 + " s");

LinkedListStack<Integer> linkedListStack = new LinkedListStack<>();
double time2 = testStack(linkedListStack, opCount);
System.out.println("LinkedListStack, time: " + time2 + " s");

// 其实这个时间比较很复杂,因为LinkedListStack中包含更多的new操作
}
}
文章作者: liuDH
文章链接: http://yoursite.com/2020/03/12/%E6%A0%88/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 毛毛裤裤的世界
打赏
  • 微信
  • 支付寶