bag, queue
This commit is contained in:
		
							parent
							
								
									6f9dc7b91b
								
							
						
					
					
						commit
						a35bb36872
					
				
					 4 changed files with 181 additions and 0 deletions
				
			
		
							
								
								
									
										51
									
								
								fundamentals/bag/bag.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								fundamentals/bag/bag.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,51 @@ | |||
| package bag | ||||
| 
 | ||||
| // "Generic" item. | ||||
| // When type parameters will land this type became | ||||
| // type Item[T any] T | ||||
| type Item interface{} | ||||
| 
 | ||||
| type Bag interface { | ||||
| 	Add(Item) | ||||
| 	Size() int | ||||
| 	IsEmpty() bool | ||||
| 	ForEach(func(Item)) | ||||
| } | ||||
| 
 | ||||
| // We use linked list as internal data structure | ||||
| // to get O(1) speed for Add operation | ||||
| type node struct { | ||||
| 	item Item | ||||
| 	next *node | ||||
| } | ||||
| 
 | ||||
| type bag struct { | ||||
| 	size int | ||||
| 	head *node | ||||
| } | ||||
| 
 | ||||
| func NewBag() Bag { | ||||
| 	return &bag{} | ||||
| } | ||||
| 
 | ||||
| func (b *bag) Add(item Item) { | ||||
| 	next := b.head | ||||
| 	b.head = &node{item, next} | ||||
| 	b.size++ | ||||
| } | ||||
| 
 | ||||
| func (b *bag) Size() int { | ||||
| 	return b.size | ||||
| } | ||||
| 
 | ||||
| func (b *bag) IsEmpty() bool { | ||||
| 	return b.size == 0 | ||||
| } | ||||
| 
 | ||||
| // As for now Go doesn't have iterators. | ||||
| // But we can simulate them with ForEach method | ||||
| func (b *bag) ForEach(f func(Item)) { | ||||
| 	for current := b.head; current != nil; current = current.next { | ||||
| 		f(current.item) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										36
									
								
								fundamentals/bag/bag_test.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								fundamentals/bag/bag_test.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | |||
| package bag | ||||
| 
 | ||||
| import ( | ||||
| 	"log" | ||||
| 	"testing" | ||||
| ) | ||||
| 
 | ||||
| func TestSimple(t *testing.T) { | ||||
| 	bag := NewBag() | ||||
| 	sum := 0 | ||||
| 
 | ||||
| 	bag.Add(1) | ||||
| 	bag.Add(2) | ||||
| 	bag.Add(3) | ||||
| 
 | ||||
| 	bag.ForEach(func(i Item) { sum += i.(int) }) | ||||
| 
 | ||||
| 	if sum != 6 { | ||||
| 		log.Fatal("wrong items in bag") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestEmpty(t *testing.T) { | ||||
| 	bag := NewBag() | ||||
| 	sum := 0 | ||||
| 
 | ||||
| 	if bag.Size() != 0 || !bag.IsEmpty() { | ||||
| 		log.Fatal("bag should be empty") | ||||
| 	} | ||||
| 
 | ||||
| 	bag.ForEach(func(i Item) { sum += i.(int) }) | ||||
| 
 | ||||
| 	if sum != 0 { | ||||
| 		log.Fatal("wrong items in bag") | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										59
									
								
								fundamentals/queue/queue.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								fundamentals/queue/queue.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,59 @@ | |||
| package queue | ||||
| 
 | ||||
| // "Generic" item. | ||||
| // When type parameters will land this type became | ||||
| // type Item[T any] T | ||||
| type Item interface{} | ||||
| 
 | ||||
| type Queue interface { | ||||
| 	Enqueue(Item) | ||||
| 	Dequeue() Item | ||||
| 	Size() int | ||||
| 	IsEmpty() bool | ||||
| } | ||||
| 
 | ||||
| // We use linked list as internal data structure | ||||
| // to get O(1) speed for push and pop opeartions | ||||
| type node struct { | ||||
| 	item Item | ||||
| 	next *node | ||||
| } | ||||
| 
 | ||||
| type queue struct { | ||||
| 	size int | ||||
| 	head *node | ||||
| 	tail *node | ||||
| } | ||||
| 
 | ||||
| func NewQueue() Queue { | ||||
| 	return &queue{} | ||||
| } | ||||
| 
 | ||||
| func (q *queue) Enqueue(item Item) { | ||||
| 	oldTail := q.tail | ||||
| 	q.tail = &node{item: item, next: nil} | ||||
| 	if q.IsEmpty() { | ||||
| 		q.head = q.tail | ||||
| 	} else { | ||||
| 		oldTail.next = q.tail | ||||
| 	} | ||||
| 	q.size++ | ||||
| } | ||||
| 
 | ||||
| func (q *queue) Dequeue() Item { | ||||
| 	first := q.head | ||||
| 	q.head = q.head.next | ||||
| 	if q.IsEmpty() { | ||||
| 		q.tail = nil | ||||
| 	} | ||||
| 	q.size-- | ||||
| 	return first.item | ||||
| } | ||||
| 
 | ||||
| func (q *queue) Size() int { | ||||
| 	return q.size | ||||
| } | ||||
| 
 | ||||
| func (q *queue) IsEmpty() bool { | ||||
| 	return q.head == nil | ||||
| } | ||||
							
								
								
									
										35
									
								
								fundamentals/queue/queue_test.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								fundamentals/queue/queue_test.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,35 @@ | |||
| package queue | ||||
| 
 | ||||
| import ( | ||||
| 	"log" | ||||
| 	"testing" | ||||
| ) | ||||
| 
 | ||||
| func TestSimple(t *testing.T) { | ||||
| 	queue := NewQueue() | ||||
| 
 | ||||
| 	queue.Enqueue(10) | ||||
| 	queue.Enqueue(20) | ||||
| 	queue.Enqueue(30) | ||||
| 
 | ||||
| 	first, second := queue.Dequeue().(int), queue.Dequeue().(int) | ||||
| 
 | ||||
| 	if first != 10 && second != 20 { | ||||
| 		log.Fatal("wrong order") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestSize(t *testing.T) { | ||||
| 	queue := NewQueue() | ||||
| 
 | ||||
| 	if queue.Size() != 0 { | ||||
| 		log.Fatal("empty queue should have size 0") | ||||
| 	} | ||||
| 	queue.Enqueue(10) | ||||
| 	queue.Enqueue(20) | ||||
| 	queue.Enqueue(30) | ||||
| 
 | ||||
| 	if queue.Size() != 3 { | ||||
| 		log.Fatal("wrong size") | ||||
| 	} | ||||
| } | ||||
		Loading…
	
	Add table
		
		Reference in a new issue