---
# System prepended metadata

title: Data Structure And Algorithms

---

## Data Structure And Algorithms

# Algorithms
## Sorting
### Bubble Sort
```go=
func BubbleSort(arr []int) []int {
	for i := 0; i < len(arr); i++ {
		for j := 0; j < len(arr)-1; j++ {
			if arr[j] > arr[j+1] {
				arr[j], arr[j+1] = arr[j+1], arr[j]
			}
		}
	}

	return arr
}
```

### Selection Sort
```go=
func SelectionSort(arr []int) []int {
	for i := 0; i < len(arr)-1; i++ {
		minIndex := i
		for j := i; j < len(arr); j++ {
			if arr[j] < arr[minIndex] {
				minIndex = j
			}
		}

		arr[i], arr[minIndex] = arr[minIndex], arr[i]
	}

	return arr
}

```
### Merge Sort
```go= 
func MergeSort(arr []int) []int {
	if len(arr) == 1 {
		return arr
	}

	mid := len(arr) / 2

	left := MergeSort(arr[:mid])
	right := MergeSort(arr[mid:])
    
	return Merge(left, right)
}

func Merge(arr1, arr2 []int) []int {
	var arr []int

	i := 0
	j := 0

	for i < len(arr1) && j < len(arr2) {
		if arr1[i] < arr2[j] {
			arr = append(arr, arr1[i])
			i++
		} else {
			arr = append(arr, arr2[j])
			j++
		}
	}

	for ; i < len(arr1); i++ {
		arr = append(arr, arr1[i])
	}

	for ; j < len(arr2); j++ {
		arr = append(arr, arr2[j])
	}

	return arr
}

```
## Searching

### Linear Search
```go=
func LinearSearch(arr []int, n int) int {
	for i := 0; i < len(arr); i++ {
		if arr[i] == n {
			return i
		}
	}

	return -1
}

```
### Binary Search
```go=
func BinarySearch(arr []int, n int) int {
	left := 0
	right := len(arr) - 1
	for left <= right {
		mid := (left + right) / 2
		if arr[mid] == n {
			return mid
		}
		if n > arr[mid] {
			left = mid + 1
		}
		if n < arr[mid] {
			right = mid - 1
		}
	}

	return -1
}
```
### Binary Search With Recursion
```go=
func BinarySearch(arr []int, n int, left int, right int) int {
	if right < left {
		return -1
	}

	mid := (left + right) / 2

	if arr[mid] == n {
		return mid
	}

	if n > arr[mid] {
		return BinarySearch(arr, n, mid+1, right)
	}

	return BinarySearch(arr, n, left, mid-1)
}
```
# Data Structure
### Queue
```go=
package main

import (
	"fmt"
)

type Queue struct {
	Items  []int
	length int
}

func NewQueue() *Queue {
	return &Queue{
		Items: make([]int, 0),
	}
}

func (q *Queue) Enqueue(n int) {
	q.Items = append(q.Items, n)
	q.length++
}

func (q *Queue) Dequeue() int {
	if q.length == 0 {
		fmt.Println("empty queue")
		return 0
	}

	first := q.Items[0]
	q.Items = q.Items[1:]
	q.length--
	return first
}

func (q *Queue) Length() int {
	return q.length
}

func main() {
	q := NewQueue()
	q.Enqueue(5)
	q.Enqueue(6)
	q.Enqueue(8)
	fmt.Println("Length :", q.Length())
	fmt.Println(q.Dequeue())
	fmt.Println("Length :", q.Length())
	fmt.Println(q.Dequeue())
	fmt.Println("Length :", q.Length())
	fmt.Println(q.Dequeue())
	fmt.Println("Length :", q.Length())
	fmt.Println(q.Dequeue())
	q.Enqueue(8)
	fmt.Println("Length :", q.Length())
	fmt.Println(q.Dequeue())
}

```
### Queue with Nodes
```go!
package main

import (
	"errors"
	"fmt"
)

func main() {
	fmt.Println("Hello World")
	q := NewQueue()
	q.Enqueue(1)
	q.Enqueue(2)
	q.Enqueue(3)
	q.Enqueue(4)

	fmt.Println(q.Dequeue())
	fmt.Println(q.Dequeue())
	fmt.Println(q.Dequeue())
	fmt.Println(q.Dequeue())
	fmt.Println(q.Dequeue())
}

type Node struct {
	Data int
	Next *Node
}

func (n *Node) HasNext() bool {
	return n.Next != nil
}

type Queue struct {
	Head *Node
}

func (q *Queue) Enqueue(val int) {
	n := &Node{Data: val}
	if q.Head == nil {
		q.Head = n
		return
	}

	cur := q.Head
	for cur.HasNext() {
		cur = cur.Next
	}

	cur.Next = n
}

func (q *Queue) Dequeue() (int, error) {
	if q.Head == nil {
		return 0, errors.New("empty queue")
	}

	val := q.Head.Data
	q.Head = q.Head.Next

	return val, nil
}

func NewQueue() *Queue {
	return &Queue{}
}

```

### Priority Queue
```go=
package main

import (
	"fmt"
)

type QueueItem struct {
	Data     int
	Priority int
}

type Queue struct {
	Items  []QueueItem
	length int
}

func NewQueue() *Queue {
	return &Queue{
		Items: make([]QueueItem, 0),
	}
}

func (q *Queue) Enqueue(n, priority int) {
	qItem := QueueItem{
		Data:     n,
		Priority: priority,
	}

	q.Items = append(q.Items, qItem)
	q.length++
	q.sort()
}

func (q *Queue) sort() {
	for i := 0; i < q.length; i++ {
		for j := 0; j < q.length-1; j++ {
			if q.Items[j].Priority < q.Items[j+1].Priority {
				q.Items[j].Data, q.Items[j+1].Data = q.Items[j+1].Data, q.Items[j].Data
			}
		}
	}
}

func (q *Queue) Dequeue() int {
	if q.length == 0 {
		fmt.Println("empty queue")
		return 0
	}

	first := q.Items[0]
	q.Items = q.Items[1:]
	q.length--
	return first.Data
}

func (q *Queue) Length() int {
	return q.length
}

func main() {
	q := NewQueue()
	q.Enqueue(5, 10)
	q.Enqueue(6, 29)
	q.Enqueue(8, 3)
	fmt.Println("Length :", q.Length())
	fmt.Println(q.Dequeue())
	fmt.Println("Length :", q.Length())
	fmt.Println(q.Dequeue())
	fmt.Println("Length :", q.Length())
	fmt.Println(q.Dequeue())
	fmt.Println("Length :", q.Length())
	fmt.Println(q.Dequeue())
	q.Enqueue(8, 2)
	fmt.Println("Length :", q.Length())
	fmt.Println(q.Dequeue())
}

```
## Round Robin With Queue
```go=
import (
	"fmt"
)

func main() {
	fmt.Println("Hello, 世界")

	q := NewQ()
	r := &RR{q}
	r.Add(func() { fmt.Println("1") })
	r.Add(func() { fmt.Println("2") })
	r.Add(func() { fmt.Println("3") })

	r.Run()
}

type RR struct {
	q *Q
}

func (rr *RR) Add(fn func()) {
	rr.q.En(fn)
}

func (rr *RR) Run() {
	for {
		fn := rr.q.De()
		fn()
		rr.Add(fn)
	}
}

type Q struct {
	items []func()
}

func NewQ() *Q {
	return &Q{
		items: make([]func(), 0, 10),
	}
}

func (q *Q) En(fn func()) {
	q.items = append(q.items, fn)
}

func (q *Q) De() func() {
	fn := q.items[0]
	q.items = q.items[1:]

	return fn
}
```
### Stack with nodes
```go!
package main

import (
	"errors"
	"fmt"
)

func main() {
	fmt.Println("Hello World")
	s := NewStack()
	s.Push(4)
	s.Push(3)
	s.Push(2)
	s.Push(1)
	fmt.Println(s.Pop())
	fmt.Println(s.Pop())
	fmt.Println(s.Pop())
	fmt.Println(s.Pop())
	fmt.Println(s.Pop())
}

type Node struct {
	Data int
	Next *Node
}

func (n *Node) HasNext() bool {
	return n.Next != nil
}

type Stack struct {
	Head *Node
}

func (s *Stack) Push(val int) {
	n := &Node{Data: val}
	if s.Head == nil {
		s.Head = n
		return
	}

	n.Next = s.Head
	s.Head = n
}

func (s *Stack) Pop() (int, error) {
	if s.Head == nil {
		return 0, errors.New("empty stack")
	}

	val := s.Head.Data
	s.Head = s.Head.Next

	return val, nil
}

func NewStack() *Stack {
	return &Stack{}
}

```
### Binary Searh Tree
```go!
package main

import (
	"fmt"
)

func main() {
	fmt.Println("Hello World")
	n := &Node{data: 1}
	bst := &BST{root: n}
	bst.insert(2)
	bst.insert(3)
	bst.insert(4)
	bst.insert(5)
	printOrder(bst.root)
	fmt.Println()
	fmt.Println(bst.find(6))
}

type Node struct {
	data  int
	left  *Node
	right *Node
}

func (n *Node) HasLeft() bool {
	return n.left != nil
}

func (n *Node) HasRight() bool {
	return n.right != nil
}

func (n *Node) Insert(value int) {
	if value < n.data {
		if n.left == nil {
			n.left = &Node{data: value}
		} else {
			n.left.Insert(value)
		}
	}

	if value > n.data {
		if n.right == nil {
			n.right = &Node{data: value}
		} else {
			n.right.Insert(value)
		}
	}
}

func (n *Node) Find(val int) int {
	if n.data == val {
		return n.data
	}

	if val < n.data && n.HasLeft() {
		return n.left.Find(val)
	}

	if val > n.data && n.HasRight() {
		return n.right.Find(val)
	}

	return -1
}

type BST struct {
	root *Node
}

func (bst *BST) insert(value int) {
	if bst.root == nil {
		bst.root = &Node{data: value}
		return
	}

	bst.root.Insert(value)
}

func (bst *BST) find(val int) int {
	if bst.root == nil {
		return -1
	}

	return bst.root.Find(val)
}

func printOrder(root *Node) {
	if root == nil {
		return
	}

	if root.HasLeft() {
		printOrder(root.left)
	}

	fmt.Print(root.data, " ")

	if root.HasRight() {
		printOrder(root.right)
	}
}

```
### HashTable
```go!
package main

import (
	"fmt"
)

func main() {
	fmt.Println("Hello World")
	ht := New()
	ht.Insert("1", 1)
	ht.Insert("22", 2)
	ht.Insert("333", 3)
	ht.Insert("4444", 4)
	ht.Insert("55555", 5)
	ht.Insert("666666", 6)
	ht.Insert("7777777", 7)

	// fmt.Println(ht.Get("1"))
	// fmt.Println(ht.Get("2"))
	// fmt.Println(ht.Get("3"))
	// fmt.Println(ht.Get("4"))
	// fmt.Println(ht.Get("5"))
	// fmt.Println(ht.Get("6"))

	ht.PrintAll()
}

type node struct {
	key   string
	value int
	next  *node
}

type list struct {
	root *node
}

func (l *list) insert(n *node) {
	if l.root == nil {
		l.root = n
		return
	}

	curr := l.root
	for curr.next != nil {
		curr = curr.next
	}

	curr.next = n
}

const size = 3

type HashTable struct {
	arr [size]*list
}

func New() *HashTable {

	var arr [size]*list

	for i := 0; i < size; i++ {
		arr[i] = &list{}
	}

	return &HashTable{
		arr: arr,
	}
}

func (h *HashTable) hash(key string) int {
	return len(key) % 3
}

func (h *HashTable) PrintAll() {
	for i := 0; i < size; i++ {
		fmt.Println("[", i, "]")
		list := h.arr[i]
		curr := list.root
		for curr != nil {
			fmt.Println(fmt.Sprintf("key %s value %d\n", curr.key, curr.value))
			curr = curr.next
		}
	}
}

func (h *HashTable) Insert(key string, value int) {
	index := h.hash(key)
	list := h.arr[index]
	gn := h.getNode(key)

	if gn != nil {
		gn.value = value
		return
	}

	n := node{
		key:   key,
		value: value,
	}

	list.insert(&n)
}

func (h *HashTable) getNode(key string) *node {
	index := h.hash(key)

	list := h.arr[index]

	curr := list.root

	for curr != nil {
		if curr.key == key {
			return curr
		}

		curr = curr.next
	}

	return nil
}

func (h *HashTable) Get(key string) int {
	index := h.hash(key)

	list := h.arr[index]

	curr := list.root

	for curr != nil {
		if curr.key == key {
			return curr.value
		}

		curr = curr.next
	}

	fmt.Println("no value found")

	return -1

}

```