## 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 } ```