Skip to content

Add details to queue and stack #139

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion queue/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,17 @@ func dequeue() (int, error) {

## Complexity

Enqueue and dequeue operations both perform in O(1) times.
Enqueue and dequeue operations both perform in O(1) times in the linked list implementation. In other traditional languages like C the linked list approach is considered to be faster than the slice approach because both enqueue and dequeue operations are O(n) due to the slice size change. In Go however slices are managed intelligently behind the scene and perform very well for just about all purposes.

We can use Go's built-in benchmarking tooling to see which implementation is faster. This is done in [slice_vs_linked_list_bench_test.go](./slice_vs_linked_list_bench_test.go). It can be executed by running `go test -bench=. -test.benchmem` in this directory. The output shows that the slice implementation is almost seven times faster.

```Shell
pkg: github.com/spring1843/go-dsa/queue
BenchmarkLinkedListQueue-8 17956176 83.73 ns/op 56 B/op 1 allocs/op
BenchmarkSliceQueue-8 100000000 11.79 ns/op 45 B/op 0 allocs/op
PASS
ok github.com/spring1843/go-dsa/queue 3.775s
```

## Application

Expand Down
63 changes: 63 additions & 0 deletions queue/slice_vs_linked_list_bench_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package queue

import (
"container/list"
"errors"
"testing"
)

type (
linkedListQueue struct {
items *list.List
}

sliceQueue []int
)

func BenchmarkLinkedListQueue(b *testing.B) {
q := newLinkedListQueue()
for n := 0; n < b.N; n++ {
q.enqueue(n)
}
for n := 0; n < b.N; n++ {
q.dequeue()
}
}

func BenchmarkSliceQueue(b *testing.B) {
q := sliceQueue{}
for n := 0; n < b.N; n++ {
q.enqueue(n)
}
for n := 0; n < b.N; n++ {
q.dequeue()
}
}

func (q *sliceQueue) enqueue(val int) {
*q = append(*q, val)
}

func (q *sliceQueue) dequeue() (int, error) {
if len(*q) == 0 {
return 0, errors.New("queue is empty")
}
value := (*q)[0]
*q = (*q)[1:]
return value, nil
}

func newLinkedListQueue() *linkedListQueue {
return &linkedListQueue{items: list.New()}
}

func (q *linkedListQueue) enqueue(val int) {
q.items.PushBack(val)
}

func (q *linkedListQueue) dequeue() (int, error) {
if q.items.Len() == 0 {
return 0, errors.New("queue is empty")
}
return q.items.Remove(q.items.Front()).(int), nil
}
2 changes: 2 additions & 0 deletions stack/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ func pop() (int, error) {

Push and pop operations in stacks are considered O(1) operations, making them highly efficient. Additionally, many machines have built-in stack instruction sets, further increasing their performance. Stacks' unique efficiency and usefulness have solidified their place as one of the most fundamental data structures, second only to [arrays](../array).

Resizing the slice and item shifting maybe necessary in the slice implementation, hence traditionally this implementation is seen as O(n). As shown in the complexity of [queue](../queue/README.md) because of the intelligent ways Go resizes the slices this is not a problem and the slice implementation of both stack and queue will perform better than the linked list implementation.

## Application

Stacks are helpful when LIFO operations are desired. Many [graph](../graph) problems are solved with stacks.
Expand Down
Loading