11# Go Stack
22
3- # 一、这是什么?为什么使用它 ?优势是啥?
3+ # 一、这是什么?为什么选它 ?优势是啥?
44
55这个项目是各种类型的栈的Go语言实现版本。
66
@@ -27,32 +27,33 @@ go get github.com/CC11001100/go-stack
2727
2828### 一览表
2929
30- | Struct名称 | 线程安全性 | 阻塞性 | 特有特性 |
31- | ---------------------- | :--------: | :----: | -------- |
32- | ArrayStack[ T any] | × | × | |
33- | SyncArrayStack[ T any] | √ | × | |
34- | LinkedStack[ T any] | × | × | |
35- | SyncLinkedStack[ T any] | √ | × | |
36- | MinStack[ T any] | × | × | |
37- | SyncMinStack[ T any] | √ | × | |
38- | MaxStack[ T any] | × | × | |
39- | SyncMaxStack [ T any] | √ | × | |
40-
41-
30+ | Struct名称 | 线程安全性 | 阻塞性 | 特有特性 |
31+ | ---------------------- | :--------: | :----: | ------------------ |
32+ | ArrayStack[ T any] | × | × | |
33+ | SyncArrayStack[ T any] | √ | × | |
34+ | LinkedStack[ T any] | × | × | |
35+ | SyncLinkedStack[ T any] | √ | × | |
36+ | MinStack[ T any] | × | × | O(1)获取栈中最小值 |
37+ | SyncMinStack[ T any] | √ | × | O(1)获取栈中最小值 |
38+ | MaxStack[ T any] | × | × | O(1)获取栈中最大值 |
39+ | SyncMaxStack [ T any] | √ | × | O(1)获取栈中最大值 |
4240
4341# 四、Interface: Stack
4442
45- 接口定义的接口定义
46-
47-
43+ 接口` Stack[T any] ` 定义了一些所有的栈都会有的API。
4844
4945## 入栈
5046
5147```
5248Push(values ...T)
5349```
5450
51+ Example:
5552
53+ ``` go
54+ stack := NewArrayStack [int ]()
55+ stack.Push (1 )
56+ ```
5657
5758## 出栈
5859
@@ -61,7 +62,41 @@ Pop() T
6162PopE() (T, error)
6263```
6364
65+ Pop Example:
66+
67+ ``` go
68+ type User struct {
69+ }
70+ stack := NewArrayStack [*User]()
71+ fmt.Println (stack.Pop ())
72+ u := &User{}
73+ stack.Push (u)
74+ fmt.Println (stack.Pop ())
75+ // Output:
76+ // <nil>
77+ // &{}
78+ ```
6479
80+ PopE Example:
81+
82+ ``` go
83+ stack := NewArrayStack [int ]()
84+ element , err := stack.PopE ()
85+ if errors.Is (err, ErrStackEmpty ) {
86+ fmt.Println (" stack empty!" )
87+ }
88+
89+ stack.Push (1 )
90+ element, err = stack.PopE ()
91+ if err != nil {
92+ fmt.Println (err.Error ())
93+ return
94+ }
95+ fmt.Println (element)
96+ // Output:
97+ // stack empty!
98+ // 1
99+ ```
65100
66101## 查看栈顶元素
67102
@@ -70,7 +105,41 @@ Peek() T
70105PeekE() (T, error)
71106```
72107
108+ Peek Example:
109+
110+ ``` go
111+ type User struct {
112+ }
113+ stack := NewArrayStack [*User]()
114+ fmt.Println (stack.Peek ())
115+ u := &User{}
116+ stack.Push (u)
117+ fmt.Println (stack.Peek ())
118+ // Output:
119+ // <nil>
120+ // &{}
121+ ```
73122
123+ PeekE Example:
124+
125+ ``` go
126+ stack := NewArrayStack [int ]()
127+ element , err := stack.PeekE ()
128+ if errors.Is (err, ErrStackEmpty ) {
129+ fmt.Println (" stack empty!" )
130+ }
131+
132+ stack.Push (1 )
133+ element, err = stack.PeekE ()
134+ if err != nil {
135+ fmt.Println (err.Error ())
136+ return
137+ }
138+ fmt.Println (element)
139+ // Output:
140+ // stack empty!
141+ // 1
142+ ```
74143
75144## 判断栈是否空
76145
@@ -79,71 +148,208 @@ IsEmpty() bool
79148IsNotEmpty() bool
80149```
81150
151+ IsEmpty Example:
152+
153+ ``` go
154+ stack := NewArrayStack [int ]()
155+ fmt.Println (stack.IsEmpty ())
156+ stack.Push (1 )
157+ fmt.Println (stack.IsEmpty ())
158+ // Output:
159+ // true
160+ // false
161+ ```
82162
163+ IsNotEmpty Example:
164+
165+ ``` go
166+ stack := NewArrayStack [int ]()
167+ fmt.Println (stack.IsNotEmpty ())
168+ stack.Push (1 )
169+ fmt.Println (stack.IsNotEmpty ())
170+ // Output:
171+ // false
172+ // true
173+ ```
83174
84175## 栈中元素个数
85176
86177```
87178Size() int
88179```
89180
181+ Example:
90182
183+ ``` go
184+ stack := NewArrayStack [int ]()
185+ stack.Push (1 )
186+ fmt.Println (stack.Size ())
187+ // Output:
188+ // 1
189+ ```
91190
92191## 清空栈
93192
94193```
95194Clear()
96195```
97196
197+ Example:
198+
199+ ``` go
200+ stack := NewArrayStack [int ]()
201+ stack.Push (1 )
202+ fmt.Println (stack.Size ())
203+ stack.Clear ()
204+ fmt.Println (stack.Size ())
205+ // Output:
206+ // 1
207+ // 0
208+ ```
98209
210+ ## String
99211
100- ## ArrayStack
212+ 把栈转为String,一般用于debug之类的把栈中所有元素可视化。
101213
102- 数组实现的栈适合频繁入栈出栈的操作
214+ Example:
103215
104- ### 数组缩容
216+ ``` go
217+ stack := NewArrayStack [int ]()
218+ stack.Push (1 )
219+ fmt.Println (stack.String ())
220+ // Output:
221+ // [1]
222+ ```
105223
106- 可能会存在的坑:类似于GO内置的map,默认情况下ArrayStack底层的数组也是只增长不缩容的,如果你的栈中的元素的个数具有先是很多,然后一直保持在一个较少的样子,建议在栈相对平稳之后调用TrimArray方法来让底层的数组释放掉短时间内不会再使用的空间。
224+ # ArrayStack
107225
108- ### 数组扩容到指定长度
226+ 基于数组实现的栈。
109227
110- 允许对底层数组进行一些微操。
228+ Example:
111229
230+ ``` go
231+ stack := NewArrayStack [int ]()
232+ fmt.Println (stack.String ())
233+ // Output:
234+ // []
235+ ```
112236
237+ # LinkedStack
113238
114- ## SyncArrayStack
239+ 基于链表实现的栈。
115240
116- ## LinkedStack
241+ Example:
117242
118- ## SyncLinkedStack
243+ ``` go
244+ stack := NewLinkedStack [int ]()
245+ fmt.Println (stack.String ())
246+ // Output:
247+ // []
248+ ```
119249
250+ # 五、最大栈 & 最小栈
120251
252+ ## MinStack && SyncMinStack
121253
122- # 五、最大栈 & 最小栈
254+ 相较于Stack接口增加了两个方法用于O(1)获取栈中所有元素的最小值:
255+
256+ ``` go
257+ GetMin () T
258+ GetMinE () (T, error )
259+ ```
123260
124- ## MinStack
261+ GetMin Example:
125262
126- ## SyncMinStack
263+ ``` go
264+ stack := NewSyncMinStack [int ](func (a, b int ) int { return a - b })
127265
128- ## MaxStack
266+ _ , err := stack.GetMinE ()
267+ assert.ErrorIs (t, err, ErrStackEmpty )
129268
130- SyncMaxStack
269+ stack.Push (10 )
270+ stack.Push (7 )
271+ stack.Push (9 )
272+ element , err := stack.GetMinE ()
273+ assert.Nil (t, err)
274+ assert.Equal (t, 7 , element)
275+ ```
131276
277+ GetMinE Example:
278+
279+ ``` go
280+ stack := NewSyncMinStack [int ](func (a, b int ) int { return a - b })
281+
282+ _ , err := stack.GetMinE ()
283+ if errors.Is (err, ErrStackEmpty ) {
284+ fmt.Println (" stack empty!" )
285+ }
286+
287+ stack.Push (10 )
288+ stack.Push (7 )
289+ stack.Push (9 )
290+ element , err := stack.GetMinE ()
291+ if err != nil {
292+ fmt.Println (err.Error ())
293+ return
294+ }
295+ fmt.Println (element)
296+ // Output:
297+ // stack empty!
298+ // 7
299+ ```
132300
301+ ## MaxStack && SyncMaxStack
133302
134- # 六、阻塞栈
303+ 相较于Stack接口增加了两个方法用于O(1)获取栈中所有元素的最小值:
135304
136- 因为仅当多个协程操作同一个栈时才需要考虑阻塞的情况,所以阻塞栈都是线程安全的。
305+ ``` go
306+ GetMax () T
307+ GetMaxE () (T, error )
308+ ```
137309
310+ GetMax Example:
138311
312+ ``` go
313+ stack := NewSyncMaxStack [int ](func (a, b int ) int { return a - b })
139314
315+ _ , err := stack.GetMaxE ()
316+ assert.ErrorIs (t, err, ErrStackEmpty )
140317
318+ stack.Push (10 )
319+ stack.Push (7 )
320+ stack.Push (9 )
321+ element , err := stack.GetMaxE ()
322+ assert.Nil (t, err)
323+ assert.Equal (t, 10 , element)
324+ ```
325+
326+ GetMaxE Example:
327+
328+ ``` go
329+ stack := NewSyncMaxStack [int ](func (a, b int ) int { return a - b })
330+
331+ _ , err := stack.GetMaxE ()
332+ if errors.Is (err, ErrStackEmpty ) {
333+ fmt.Println (" stack empty!" )
334+ }
335+
336+ stack.Push (10 )
337+ stack.Push (7 )
338+ stack.Push (9 )
339+ element , err := stack.GetMaxE ()
340+ if err != nil {
341+ fmt.Println (err.Error ())
342+ return
343+ }
344+ fmt.Println (element)
345+ // Output:
346+ // stack empty!
347+ // 10
348+ ```
141349
142350# TODO
143351
144- TODO 2022-10-22 02:07:40 Code Review
145- TODO 2022-10-22 02:04:55 测试
146- TODO 2022-10-22 02:03:14 编写文档
352+ 实现阻塞栈,因为仅当多个协程操作同一个栈时才需要考虑阻塞的情况,所以阻塞栈都是线程安全的。
147353
148354
149355
0 commit comments