Skip to content
Open
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
98 changes: 98 additions & 0 deletions non_linear/graphs/TarjanAlgorithm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package main

import "fmt"

type Graph struct {
vertices int
adjList map[int][]int
}

func NewGraph(vertices int) *Graph {
return &Graph{
vertices: vertices,
adjList: make(map[int][]int),
}
}

func (g *Graph) AddEdge(v, w int) {
g.adjList[v] = append(g.adjList[v], w)
}

func (g *Graph) TarjanSCC() [][]int {
index := 0
indices := make([]int, g.vertices)
lowLink := make([]int, g.vertices)
onStack := make([]bool, g.vertices)
stack := []int{}
result := [][]int{}

for i := 0; i < g.vertices; i++ {
indices[i] = -1
}

var strongConnect func(v int)
strongConnect = func(v int) {
indices[v] = index
lowLink[v] = index
index++
stack = append(stack, v)
onStack[v] = true

for _, w := range g.adjList[v] {
if indices[w] == -1 {
strongConnect(w)
lowLink[v] = min(lowLink[v], lowLink[w])
} else if onStack[w] {
lowLink[v] = min(lowLink[v], indices[w])
}
}

if lowLink[v] == indices[v] {
scc := []int{}
for {
w := stack[len(stack)-1]
stack = stack[:len(stack)-1]
onStack[w] = false
scc = append(scc, w)
if w == v {
break
}
}
result = append(result, scc)
}
}

for i := 0; i < g.vertices; i++ {
if indices[i] == -1 {
strongConnect(i)
}
}

return result
}

func min(a, b int) int {
if a < b {
return a
}
return b
}

func main() {
g := NewGraph(8)
g.AddEdge(0, 1)
g.AddEdge(1, 2)
g.AddEdge(2, 0)
g.AddEdge(3, 4)
g.AddEdge(4, 5)
g.AddEdge(5, 3)
g.AddEdge(6, 4)
g.AddEdge(6, 7)
g.AddEdge(7, 6)

fmt.Println("Strongly Connected Components:")
sccs := g.TarjanSCC()
for i, scc := range sccs {
fmt.Printf("SCC %d: %v\n", i+1, scc)
}
}
97 changes: 97 additions & 0 deletions non_linear/trie/radix_tree.go
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a main() func which tests the implementation with test cases.

Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package radixtree
type Node struct {
Key rune
Children map[rune]*Node
IsComplete bool
}


func NewNode(key rune) *Node {
return &Node{
Key: key,
Children: make(map[rune]*Node),
}
}


func (n *Node) AddChild(key rune, isComplete bool) *Node {
child, exists := n.Children[key]
if !exists {
child = NewNode(key)
n.Children[key] = child
}
if isComplete {
child.IsComplete = true
}
return child
}


func (n *Node) GetChild(key rune) *Node {
return n.Children[key]
}


func (n *Node) RemoveChild(key rune) {
delete(n.Children, key)
}
type RadixTree struct {
Head *Node
}


func NewRadixTree() *RadixTree {
return &RadixTree{
Head: NewNode('*'),
}
}


func (t *RadixTree) Insert(word string) {
currentNode := t.Head
for i, char := range word {
isComplete := i == len(word)-1
currentNode = currentNode.AddChild(char, isComplete)
}
}


func (t *RadixTree) Delete(word string) {
var depthFirstDelete func(currentNode *Node, index int)
depthFirstDelete = func(currentNode *Node, index int) {
if index >= len(word) {
return
}
char := rune(word[index])
nextNode := currentNode.GetChild(char)
if nextNode == nil {
return
}
depthFirstDelete(nextNode, index+1)
if index == len(word)-1 {
nextNode.IsComplete = false
}
if len(nextNode.Children) == 0 && !nextNode.IsComplete {
currentNode.RemoveChild(char)
}
}
depthFirstDelete(t.Head, 0)
}


func (t *RadixTree) Find(word string) bool {
node := t.getLastCharacterNode(word)
return node != nil && node.IsComplete
}


func (t *RadixTree) getLastCharacterNode(word string) *Node {
currentNode := t.Head
for _, char := range word {
currentNode = currentNode.GetChild(char)
if currentNode == nil {
return nil
}
}
return currentNode
}