🎯 Ejemplos recomendados
Balanced sample collections from various categories for you to explore
Ejemplos de Estructuras de Datos Web Go
Ejemplos de estructuras de datos Web Go incluyendo slices, maps, listas y estructuras de árbol
💻 Slices y Arrays go
🟢 simple
⭐⭐
Trabajar con slices y arrays incluyendo creación, manipulación y operaciones comunes
⏱️ 15 min
🏷️ go, web, data structures
Prerequisites:
Basic Go
// Web Go Slices and Arrays Examples
// Working with Go slices and arrays
package main
import (
"fmt"
"sort"
"strings"
)
// 1. Creating Slices
// CreateSlicesExample demonstrates various ways to create slices
func CreateSlicesExample() {
fmt.Println("--- Creating Slices ---")
// Method 1: Using make
slice1 := make([]int, 5) // Creates slice of length 5
slice2 := make([]int, 3, 10) // Creates slice of length 3, capacity 10
fmt.Printf("slice1: %v (len=%d, cap=%d)\n", slice1, len(slice1), cap(slice1))
fmt.Printf("slice2: %v (len=%d, cap=%d)\n", slice2, len(slice2), cap(slice2))
// Method 2: Slice literal
slice3 := []int{1, 2, 3, 4, 5}
fmt.Printf("slice3: %v\n", slice3)
// Method 3: From array
array := [5]int{1, 2, 3, 4, 5}
slice4 := array[1:4] // Creates slice [2, 3, 4]
fmt.Printf("slice4: %v\n", slice4)
// Method 4: Empty slice
var slice5 []int
fmt.Printf("slice5: %v (nil=%v)\n", slice5, slice5 == nil)
}
// 2. Adding Elements
// AddElementsExample demonstrates adding elements to slices
func AddElementsExample() {
fmt.Println("\n--- Adding Elements ---")
slice := []int{1, 2, 3}
// Append single element
slice = append(slice, 4)
fmt.Printf("After append(4): %v\n", slice)
// Append multiple elements
slice = append(slice, 5, 6, 7)
fmt.Printf("After append(5,6,7): %v\n", slice)
// Append another slice
anotherSlice := []int{8, 9, 10}
slice = append(slice, anotherSlice...)
fmt.Printf("After append(anotherSlice): %v\n", slice)
}
// 3. Accessing and Modifying Elements
// AccessModifyExample demonstrates accessing and modifying elements
func AccessModifyExample() {
fmt.Println("\n--- Accessing and Modifying ---")
slice := []string{"apple", "banana", "cherry"}
// Access elements
fmt.Printf("First element: %s\n", slice[0])
fmt.Printf("Last element: %s\n", slice[len(slice)-1])
// Modify elements
slice[1] = "blueberry"
fmt.Printf("After modification: %v\n", slice)
// Using range to access
fmt.Print("Using range: ")
for i, value := range slice {
fmt.Printf("[%d]=%s ", i, value)
}
fmt.Println()
}
// 4. Slicing Operations
// SlicingExample demonstrates slice operations
func SlicingExample() {
fmt.Println("\n--- Slicing Operations ---")
slice := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
// Different slicing operations
fmt.Printf("Original: %v\n", slice)
fmt.Printf("slice[2:5]: %v\n", slice[2:5]) // [2 3 4]
fmt.Printf("slice[:5]: %v\n", slice[:5]) // [0 1 2 3 4]
fmt.Printf("slice[5:]: %v\n", slice[5:]) // [5 6 7 8 9]
fmt.Printf("slice[:]: %v\n", slice[:]) // [0 1 2 3 4 5 6 7 8 9]
// Create sub-slice
subSlice := slice[3:7]
fmt.Printf("subSlice: %v\n", subSlice)
}
// 5. Deleting Elements
// DeleteElementsExample demonstrates deleting elements from slices
func DeleteElementsExample() {
fmt.Println("\n--- Deleting Elements ---")
slice := []int{1, 2, 3, 4, 5, 6, 7}
// Delete first element
slice = slice[1:]
fmt.Printf("Delete first: %v\n", slice)
// Delete last element
slice = slice[:len(slice)-1]
fmt.Printf("Delete last: %v\n", slice)
// Delete middle element (index 2)
index := 2
slice = append(slice[:index], slice[index+1:]...)
fmt.Printf("Delete index %d: %v\n", index, slice)
// Delete multiple elements (remove elements at indices 1-2)
slice = append(slice[:1], slice[3:]...)
fmt.Printf("Delete range [1:3]: %v\n", slice)
}
// 6. Copying Slices
// CopySlicesExample demonstrates copying slices
func CopySlicesExample() {
fmt.Println("\n--- Copying Slices ---")
original := []int{1, 2, 3, 4, 5}
// Method 1: Using copy
copied := make([]int, len(original))
copy(copied, original)
fmt.Printf("Original: %v\n", original)
fmt.Printf("Copied: %v\n", copied)
// Modify copy
copied[0] = 999
fmt.Printf("After modifying copy: %v\n", copied)
fmt.Printf("Original unchanged: %v\n", original)
// Method 2: Using append
copied2 := append([]int{}, original...)
fmt.Printf("Copied2: %v\n", copied2)
}
// 7. Sorting Slices
// SortSlicesExample demonstrates sorting operations
func SortSlicesExample() {
fmt.Println("\n--- Sorting Slices ---")
// Sort integers
numbers := []int{5, 2, 8, 1, 9, 3}
sort.Ints(numbers)
fmt.Printf("Sorted integers: %v\n", numbers)
// Sort strings
fruits := []string{"banana", "apple", "cherry"}
sort.Strings(fruits)
fmt.Printf("Sorted strings: %v\n", fruits)
// Custom sort with reverse
numbers2 := []int{5, 2, 8, 1, 9, 3}
sort.Sort(sort.Reverse(sort.IntSlice(numbers2)))
fmt.Printf("Reverse sorted: %v\n", numbers2)
// Check if sorted
isSorted := sort.IntsAreSorted(numbers)
fmt.Printf("Is sorted: %v\n", isSorted)
}
// 8. Searching Slices
// SearchSlicesExample demonstrates searching in slices
func SearchSlicesExample() {
fmt.Println("\n--- Searching Slices ---")
slice := []string{"apple", "banana", "cherry", "date"}
// Linear search
target := "cherry"
found := false
index := -1
for i, v := range slice {
if v == target {
found = true
index = i
break
}
}
if found {
fmt.Printf("Found '%s' at index %d\n", target, index)
} else {
fmt.Printf("'%s' not found\n", target)
}
// Binary search (requires sorted slice)
sort.Strings(slice)
target = "banana"
index = sort.SearchStrings(slice, target)
if index < len(slice) && slice[index] == target {
fmt.Printf("Binary search found '%s' at index %d\n", target, index)
}
}
// 9. Filtering Slices
// FilterSlicesExample demonstrates filtering operations
func FilterSlicesExample() {
fmt.Println("\n--- Filtering Slices ---")
numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
// Filter even numbers
var evens []int
for _, num := range numbers {
if num%2 == 0 {
evens = append(evens, num)
}
}
fmt.Printf("Even numbers: %v\n", evens)
// Filter numbers greater than 5
var greaterThanFive []int
for _, num := range numbers {
if num > 5 {
greaterThanFive = append(greaterThanFive, num)
}
}
fmt.Printf("Greater than 5: %v\n", greaterThanFive)
}
// 10. Transforming Slices (Map)
// TransformSlicesExample demonstrates slice transformation
func TransformSlicesExample() {
fmt.Println("\n--- Transforming Slices ---")
numbers := []int{1, 2, 3, 4, 5}
// Double each element
doubled := make([]int, len(numbers))
for i, num := range numbers {
doubled[i] = num * 2
}
fmt.Printf("Doubled: %v\n", doubled)
// Convert to strings
strings := make([]string, len(numbers))
for i, num := range numbers {
strings[i] = fmt.Sprintf("num_%d", num)
}
fmt.Printf("Strings: %v\n", strings)
}
// 11. Reducing Slices
// ReduceSlicesExample demonstrates reduce operations
func ReduceSlicesExample() {
fmt.Println("\n--- Reducing Slices ---")
numbers := []int{1, 2, 3, 4, 5}
// Sum
sum := 0
for _, num := range numbers {
sum += num
}
fmt.Printf("Sum: %d\n", sum)
// Product
product := 1
for _, num := range numbers {
product *= num
}
fmt.Printf("Product: %d\n", product)
// Max
max := numbers[0]
for _, num := range numbers {
if num > max {
max = num
}
}
fmt.Printf("Max: %d\n", max)
// Min
min := numbers[0]
for _, num := range numbers {
if num < min {
min = num
}
}
fmt.Printf("Min: %d\n", min)
}
// 12. Multidimensional Slices
// MultiDimExample demonstrates multidimensional slices
func MultiDimExample() {
fmt.Println("\n--- Multidimensional Slices ---")
// Create 2D slice
matrix := [][]int{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9},
}
fmt.Println("Matrix:")
for i, row := range matrix {
fmt.Printf("Row %d: %v\n", i, row)
}
// Access elements
fmt.Printf("matrix[1][2] = %d\n", matrix[1][2])
// Create triangular slice
triangular := [][]int{
{1},
{2, 3},
{4, 5, 6},
}
fmt.Println("\nTriangular:")
for i, row := range triangular {
fmt.Printf("Row %d: %v\n", i, row)
}
}
// 13. Common Slice Algorithms
// CommonAlgorithmsExample demonstrates common algorithms
func CommonAlgorithmsExample() {
fmt.Println("\n--- Common Algorithms ---")
// Reverse slice
slice := []int{1, 2, 3, 4, 5}
for i, j := 0, len(slice)-1; i < j; i, j = i+1, j-1 {
slice[i], slice[j] = slice[j], slice[i]
}
fmt.Printf("Reversed: %v\n", slice)
// Remove duplicates
duplicates := []int{1, 2, 2, 3, 4, 4, 5}
unique := make([]int, 0)
seen := make(map[int]bool)
for _, num := range duplicates {
if !seen[num] {
seen[num] = true
unique = append(unique, num)
}
}
fmt.Printf("Unique: %v\n", unique)
// Intersection
slice1 := []int{1, 2, 3, 4, 5}
slice2 := []int{4, 5, 6, 7, 8}
intersection := []int{}
set := make(map[int]bool)
for _, num := range slice2 {
set[num] = true
}
for _, num := range slice1 {
if set[num] {
intersection = append(intersection, num)
}
}
fmt.Printf("Intersection: %v\n", intersection)
}
// 14. Slice Utilities
// SliceContains checks if slice contains element
func SliceContains(slice []string, element string) bool {
for _, v := range slice {
if v == element {
return true
}
}
return false
}
// SliceIndex returns index of element or -1
func SliceIndex(slice []string, element string) int {
for i, v := range slice {
if v == element {
return i
}
}
return -1
}
// SliceJoin joins slice elements with separator
func SliceJoin(slice []string, sep string) string {
return strings.Join(slice, sep)
}
// SliceUtilitiesExample demonstrates utility functions
func SliceUtilitiesExample() {
fmt.Println("\n--- Slice Utilities ---")
fruits := []string{"apple", "banana", "cherry"}
// Contains
fmt.Printf("Contains 'banana': %v\n", SliceContains(fruits, "banana"))
fmt.Printf("Contains 'grape': %v\n", SliceContains(fruits, "grape"))
// Index
fmt.Printf("Index of 'cherry': %d\n", SliceIndex(fruits, "cherry"))
// Join
fmt.Printf("Joined: %s\n", SliceJoin(fruits, ", "))
}
// Main function
func main() {
fmt.Println("=== Web Go Slices and Arrays Examples ===\n")
CreateSlicesExample()
AddElementsExample()
AccessModifyExample()
SlicingExample()
DeleteElementsExample()
CopySlicesExample()
SortSlicesExample()
SearchSlicesExample()
FilterSlicesExample()
TransformSlicesExample()
ReduceSlicesExample()
MultiDimExample()
CommonAlgorithmsExample()
SliceUtilitiesExample()
fmt.Println("\n=== All Slices and Arrays Examples Completed ===")
}
💻 Maps y Diccionarios go
🟢 simple
⭐⭐
Usar maps para almacenamiento clave-valor, búsqueda y manipulación
⏱️ 15 min
🏷️ go, web, data structures
Prerequisites:
Basic Go
// Web Go Maps and Dictionaries Examples
// Working with Go maps for key-value storage
package main
import (
"fmt"
"sort"
"strings"
)
// 1. Creating Maps
// CreateMapsExample demonstrates various ways to create maps
func CreateMapsExample() {
fmt.Println("--- Creating Maps ---")
// Method 1: Using make
map1 := make(map[string]int)
fmt.Printf("Empty map: %v\n", map1)
// Method 2: Map literal
map2 := map[string]int{
"apple": 5,
"banana": 3,
"cherry": 8,
}
fmt.Printf("Map literal: %v\n", map2)
// Method 3: Empty map
var map3 map[string]int
fmt.Printf("Nil map: %v (nil=%v)\n", map3, map3 == nil)
}
// 2. Adding and Updating Elements
// AddUpdateElementsExample demonstrates adding/updating map entries
func AddUpdateElementsExample() {
fmt.Println("\n--- Adding and Updating Elements ---")
// Create map
fruits := map[string]int{
"apple": 5,
"banana": 3,
}
fmt.Printf("Initial: %v\n", fruits)
// Add new element
fruits["cherry"] = 8
fmt.Printf("After adding cherry: %v\n", fruits)
// Update existing element
fruits["apple"] = 10
fmt.Printf("After updating apple: %v\n", fruits)
// Add or update using function
fruits["date"] = fruits["date"] + 1
fmt.Printf("After add/update date: %v\n", fruits)
}
// 3. Accessing Elements
// AccessElementsExample demonstrates accessing map elements
func AccessElementsExample() {
fmt.Println("\n--- Accessing Elements ---")
scores := map[string]int{
"Alice": 95,
"Bob": 87,
"Charlie": 92,
}
// Access existing key
aliceScore := scores["Alice"]
fmt.Printf("Alice's score: %d\n", aliceScore)
// Access non-existing key (returns zero value)
davidScore := scores["David"]
fmt.Printf("David's score (zero value): %d\n", davidScore)
// Check if key exists
value, exists := scores["Bob"]
if exists {
fmt.Printf("Bob's score: %d\n", value)
}
value, exists = scores["Eve"]
if !exists {
fmt.Printf("Eve not found in map\n")
}
}
// 4. Deleting Elements
// DeleteElementsExample demonstrates deleting map entries
func DeleteElementsExample() {
fmt.Println("\n--- Deleting Elements ---")
m := map[string]int{
"one": 1,
"two": 2,
"three": 3,
"four": 4,
}
fmt.Printf("Initial: %v\n", m)
// Delete key
delete(m, "two")
fmt.Printf("After deleting 'two': %v\n", m)
// Delete non-existing key (no error)
delete(m, "five")
fmt.Printf("After deleting 'five' (no error): %v\n", m)
}
// 5. Iterating Over Maps
// IterateMapsExample demonstrates map iteration
func IterateMapsExample() {
fmt.Println("\n--- Iterating Over Maps ---")
ages := map[string]int{
"Alice": 30,
"Bob": 25,
"Charlie": 35,
}
// Iterate over key-value pairs
fmt.Println("All entries:")
for name, age := range ages {
fmt.Printf(" %s: %d\n", name, age)
}
// Iterate over keys
fmt.Println("\nAll names:")
for name := range ages {
fmt.Printf(" %s\n", name)
}
// Iterate over values
fmt.Println("\nAll ages:")
for _, age := range ages {
fmt.Printf(" %d\n", age)
}
}
// 6. Map Operations
// MapOperationsExample demonstrates common map operations
func MapOperationsExample() {
fmt.Println("\n--- Map Operations ---")
// Size
m := map[string]int{
"a": 1, "b": 2, "c": 3,
}
fmt.Printf("Map size: %d\n", len(m))
// Check if empty
isEmpty := len(m) == 0
fmt.Printf("Is empty: %v\n", isEmpty)
// Clear map (create new one)
m = make(map[string]int)
fmt.Printf("After clearing: %v (size=%d)\n", m, len(m))
}
// 7. Map with Struct Values
// MapWithStructExample demonstrates maps with struct values
func MapWithStructExample() {
fmt.Println("\n--- Map with Struct Values ---")
// Person struct
type Person struct {
Name string
Age int
City string
}
// Map with struct values
people := map[string]Person{
"p1": {Name: "Alice", Age: 30, City: "NYC"},
"p2": {Name: "Bob", Age: 25, City: "LA"},
}
// Access struct fields
fmt.Printf("p1: %s, %d, %s\n",
people["p1"].Name,
people["p1"].Age,
people["p1"].City)
// Modify struct
p := people["p2"]
p.Age = 26
people["p2"] = p
fmt.Printf("Updated p2: %s, %d\n", people["p2"].Name, people["p2"].Age)
}
// 8. Nested Maps
// NestedMapExample demonstrates nested maps
func NestedMapExample() {
fmt.Println("\n--- Nested Maps ---")
// Map of maps
departments := map[string]map[string]int{
"Engineering": {
"Alice": 30,
"Bob": 25,
},
"Sales": {
"Charlie": 35,
"David": 28,
},
}
// Access nested map
engineers := departments["Engineering"]
fmt.Printf("Engineering department: %v\n", engineers)
// Add to nested map
departments["Marketing"] = map[string]int{
"Eve": 32,
}
fmt.Printf("All departments: %v\n", departments)
}
// 9. Map Keys and Values Slices
// KeysValuesExample demonstrates extracting keys and values
func KeysValuesExample() {
fmt.Println("\n--- Extract Keys and Values ---")
scores := map[string]int{
"Alice": 95,
"Bob": 87,
"Charlie": 92,
}
// Get keys
keys := make([]string, 0, len(scores))
for key := range scores {
keys = append(keys, key)
}
sort.Strings(keys)
fmt.Printf("Sorted keys: %v\n", keys)
// Get values
values := make([]int, 0, len(scores))
for _, value := range scores {
values = append(values, value)
}
sort.Ints(values)
fmt.Printf("Sorted values: %v\n", values)
}
// 10. Map Filtering
// FilterMapExample demonstrates filtering map entries
func FilterMapExample() {
fmt.Println("\n--- Filtering Maps ---")
scores := map[string]int{
"Alice": 95,
"Bob": 67,
"Charlie": 82,
"David": 58,
"Eve": 91,
}
// Filter high scores (>= 80)
highScores := make(map[string]int)
for name, score := range scores {
if score >= 80 {
highScores[name] = score
}
}
fmt.Printf("High scores (>=80): %v\n", highScores)
// Filter by name length
shortNames := make(map[string]int)
for name, score := range scores {
if len(name) <= 4 {
shortNames[name] = score
}
}
fmt.Printf("Short names (<=4 chars): %v\n", shortNames)
}
// 11. Map Transformation
// TransformMapExample demonstrates map transformation
func TransformMapExample() {
fmt.Println("\n--- Transforming Maps ---")
prices := map[string]float64{
"apple": 1.50,
"banana": 0.75,
"cherry": 2.00,
}
// Apply discount (10% off)
discounted := make(map[string]float64)
for item, price := range prices {
discounted[item] = price * 0.9
}
fmt.Printf("Original prices: %v\n", prices)
fmt.Printf("Discounted prices: %v\n", discounted)
// Convert to uppercase keys
upperKeys := make(map[string]float64)
for item, price := range prices {
upperKeys[strings.ToUpper(item)] = price
}
fmt.Printf("Uppercase keys: %v\n", upperKeys)
}
// 12. Map Comparison
// CompareMapsExample demonstrates comparing maps
func CompareMapsExample() {
fmt.Println("\n--- Comparing Maps ---")
map1 := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
map2 := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
map3 := map[string]int{
"a": 1,
"b": 2,
"c": 4, // Different value
}
// Check equality
equal := len(map1) == len(map2)
if equal {
for key, value := range map1 {
if map2[key] != value {
equal = false
break
}
}
}
fmt.Printf("map1 == map2: %v\n", equal)
equal = len(map1) == len(map3)
if equal {
for key, value := range map1 {
if map3[key] != value {
equal = false
break
}
}
}
fmt.Printf("map1 == map3: %v\n", equal)
}
// 13. Map Merging
// MergeMapsExample demonstrates merging maps
func MergeMapsExample() {
fmt.Println("\n--- Merging Maps ---")
map1 := map[string]int{
"a": 1,
"b": 2,
}
map2 := map[string]int{
"b": 3, // Override
"c": 4,
}
// Merge (map2 values override map1)
merged := make(map[string]int)
// Copy map1
for key, value := range map1 {
merged[key] = value
}
// Add/override with map2
for key, value := range map2 {
merged[key] = value
}
fmt.Printf("map1: %v\n", map1)
fmt.Printf("map2: %v\n", map2)
fmt.Printf("merged: %v\n", merged)
}
// 14. Counting with Maps
// CountWithMapExample demonstrates counting with maps
func CountWithMapExample() {
fmt.Println("\n--- Counting with Maps ---")
// Count word frequencies
text := "apple banana apple cherry banana apple"
words := strings.Split(text, " ")
frequency := make(map[string]int)
for _, word := range words {
frequency[word]++
}
fmt.Println("Word frequencies:")
for word, count := range frequency {
fmt.Printf(" %s: %d\n", word, count)
}
// Group by parity
numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
groups := make(map[string][]int)
for _, num := range numbers {
if num%2 == 0 {
groups["even"] = append(groups["even"], num)
} else {
groups["odd"] = append(groups["odd"], num)
}
}
fmt.Println("\nGroups by parity:")
for group, nums := range groups {
fmt.Printf(" %s: %v\n", group, nums)
}
}
// 15. Map Utilities
// MapKeys returns all keys as a slice
func MapKeys(m map[string]int) []string {
keys := make([]string, 0, len(m))
for key := range m {
keys = append(keys, key)
}
return keys
}
// MapValues returns all values as a slice
func MapValues(m map[string]int) []int {
values := make([]int, 0, len(m))
for _, value := range m {
values = append(values, value)
}
return values
}
// CopyMap creates a shallow copy of map
func CopyMap(m map[string]int) map[string]int {
copy := make(map[string]int)
for key, value := range m {
copy[key] = value
}
return copy
}
// MapUtilitiesExample demonstrates utility functions
func MapUtilitiesExample() {
fmt.Println("\n--- Map Utilities ---")
m := map[string]int{
"apple": 5,
"banana": 3,
"cherry": 8,
}
fmt.Printf("Keys: %v\n", MapKeys(m))
fmt.Printf("Values: %v\n", MapValues(m))
m2 := CopyMap(m)
m2["date"] = 10
fmt.Printf("Original: %v\n", m)
fmt.Printf("Copy: %v\n", m2)
}
// Main function
func main() {
fmt.Println("=== Web Go Maps and Dictionaries Examples ===\n")
CreateMapsExample()
AddUpdateElementsExample()
AccessElementsExample()
DeleteElementsExample()
IterateMapsExample()
MapOperationsExample()
MapWithStructExample()
NestedMapExample()
KeysValuesExample()
FilterMapExample()
TransformMapExample()
CompareMapsExample()
MergeMapsExample()
CountWithMapExample()
MapUtilitiesExample()
fmt.Println("\n=== All Maps and Dictionaries Examples Completed ===")
}
💻 Árboles y Grafos go
🔴 complex
⭐⭐⭐⭐
Implementar árboles binarios, recorrido de árboles y estructuras de datos de grafos
⏱️ 30 min
🏷️ go, web, data structures
Prerequisites:
Advanced Go, data structures, algorithms
// Web Go Trees and Graphs Examples
// Implementing tree and graph data structures
package main
import (
"container/list"
"fmt"
)
// 1. Binary Tree Node
// TreeNode represents a binary tree node
type TreeNode struct {
Value int
Left *TreeNode
Right *TreeNode
}
// NewTreeNode creates a new tree node
func NewTreeNode(value int) *TreeNode {
return &TreeNode{Value: value}
}
// 2. Binary Tree Operations
// Insert inserts a value into the BST
func (n *TreeNode) Insert(value int) *TreeNode {
if n == nil {
return NewTreeNode(value)
}
if value < n.Value {
n.Left = n.Left.Insert(value)
} else {
n.Right = n.Right.Insert(value)
}
return n
}
// Search searches for a value in the BST
func (n *TreeNode) Search(value int) bool {
if n == nil {
return false
}
if value == n.Value {
return true
}
if value < n.Value {
return n.Left.Search(value)
}
return n.Right.Search(value)
}
// FindMin finds minimum value in BST
func (n *TreeNode) FindMin() *TreeNode {
current := n
for current.Left != nil {
current = current.Left
}
return current
}
// FindMax finds maximum value in BST
func (n *TreeNode) FindMax() *TreeNode {
current := n
for current.Right != nil {
current = current.Right
}
return current
}
// 3. Tree Traversals
// InOrder traversal (Left, Root, Right)
func (n *TreeNode) InOrder() []int {
result := []int{}
n.inOrder(&result)
return result
}
func (n *TreeNode) inOrder(result *[]int) {
if n == nil {
return
}
n.Left.inOrder(result)
*result = append(*result, n.Value)
n.Right.inOrder(result)
}
// PreOrder traversal (Root, Left, Right)
func (n *TreeNode) PreOrder() []int {
result := []int{}
n.preOrder(&result)
return result
}
func (n *TreeNode) preOrder(result *[]int) {
if n == nil {
return
}
*result = append(*result, n.Value)
n.Left.preOrder(result)
n.Right.preOrder(result)
}
// PostOrder traversal (Left, Right, Root)
func (n *TreeNode) PostOrder() []int {
result := []int{}
n.postOrder(&result)
return result
}
func (n *TreeNode) postOrder(result *[]int) {
if n == nil {
return
}
n.Left.postOrder(result)
n.Right.postOrder(result)
*result = append(*result, n.Value)
}
// LevelOrder traversal (BFS)
func (n *TreeNode) LevelOrder() []int {
if n == nil {
return []int{}
}
result := []int{}
queue := []*TreeNode{n}
for len(queue) > 0 {
current := queue[0]
queue = queue[1:]
result = append(result, current.Value)
if current.Left != nil {
queue = append(queue, current.Left)
}
if current.Right != nil {
queue = append(queue, current.Right)
}
}
return result
}
// 4. Tree Properties
// Height calculates tree height
func (n *TreeNode) Height() int {
if n == nil {
return 0
}
leftHeight := n.Left.Height()
rightHeight := n.Right.Height()
if leftHeight > rightHeight {
return leftHeight + 1
}
return rightHeight + 1
}
// Size counts all nodes
func (n *TreeNode) Size() int {
if n == nil {
return 0
}
return 1 + n.Left.Size() + n.Right.Size()
}
// IsLeaf checks if node is leaf
func (n *TreeNode) IsLeaf() bool {
return n.Left == nil && n.Right == nil
}
// CountLeaves counts leaf nodes
func (n *TreeNode) CountLeaves() int {
if n == nil {
return 0
}
if n.IsLeaf() {
return 1
}
return n.Left.CountLeaves() + n.Right.CountLeaves()
}
// 5. Tree Examples
// BinaryTreeExample demonstrates binary tree operations
func BinaryTreeExample() {
fmt.Println("--- Binary Tree Example ---")
// Create BST
root := NewTreeNode(50)
root.Insert(30)
root.Insert(70)
root.Insert(20)
root.Insert(40)
root.Insert(60)
root.Insert(80)
fmt.Printf("Tree structure:\n")
fmt.Printf(" 50\n")
fmt.Printf(" / \\\n")
fmt.Printf(" 30 70\n")
fmt.Printf(" / \ / \\\n")
fmt.Printf("20 40 60 80\n\n")
// Traversals
fmt.Printf("InOrder: %v\n", root.InOrder())
fmt.Printf("PreOrder: %v\n", root.PreOrder())
fmt.Printf("PostOrder: %v\n", root.PostOrder())
fmt.Printf("LevelOrder: %v\n", root.LevelOrder())
// Properties
fmt.Printf("Height: %d\n", root.Height())
fmt.Printf("Size: %d\n", root.Size())
fmt.Printf("Leaves: %d\n", root.CountLeaves())
// Search
fmt.Printf("Search 40: %v\n", root.Search(40))
fmt.Printf("Search 45: %v\n", root.Search(45))
// Min/Max
minNode := root.FindMin()
maxNode := root.FindMax()
fmt.Printf("Min: %d\n", minNode.Value)
fmt.Printf("Max: %d\n", maxNode.Value)
}
// 6. Graph Implementation
// Graph represents an adjacency list graph
type Graph struct {
vertices map[string][]string
directed bool
}
// NewGraph creates a new graph
func NewGraph(directed bool) *Graph {
return &Graph{
vertices: make(map[string][]string),
directed: directed,
}
}
// AddVertex adds a vertex
func (g *Graph) AddVertex(vertex string) {
if _, exists := g.vertices[vertex]; !exists {
g.vertices[vertex] = []string{}
}
}
// AddEdge adds an edge between vertices
func (g *Graph) AddEdge(from, to string) {
if _, exists := g.vertices[from]; !exists {
g.AddVertex(from)
}
if _, exists := g.vertices[to]; !exists {
g.AddVertex(to)
}
g.vertices[from] = append(g.vertices[from], to)
if !g.directed {
g.vertices[to] = append(g.vertices[to], from)
}
}
// GetVertices returns all vertices
func (g *Graph) GetVertices() []string {
vertices := make([]string, 0, len(g.vertices))
for v := range g.vertices {
vertices = append(vertices, v)
}
return vertices
}
// GetNeighbors returns neighbors of a vertex
func (g *Graph) GetNeighbors(vertex string) []string {
if neighbors, exists := g.vertices[vertex]; exists {
return neighbors
}
return []string{}
}
// 7. Graph Traversals
// BFS performs breadth-first search
func (g *Graph) BFS(start string) []string {
visited := make(map[string]bool)
queue := []string{start}
result := []string{}
visited[start] = true
for len(queue) > 0 {
vertex := queue[0]
queue = queue[1:]
result = append(result, vertex)
for _, neighbor := range g.GetNeighbors(vertex) {
if !visited[neighbor] {
visited[neighbor] = true
queue = append(queue, neighbor)
}
}
}
return result
}
// DFS performs depth-first search (iterative)
func (g *Graph) DFS(start string) []string {
visited := make(map[string]bool)
stack := []string{start}
result := []string{}
for len(stack) > 0 {
// Pop from stack
vertex := stack[len(stack)-1]
stack = stack[:len(stack)-1]
if !visited[vertex] {
visited[vertex] = true
result = append(result, vertex)
// Add neighbors in reverse order
neighbors := g.GetNeighbors(vertex)
for i := len(neighbors) - 1; i >= 0; i-- {
if !visited[neighbors[i]] {
stack = append(stack, neighbors[i])
}
}
}
}
return result
}
// DFSRecursive performs recursive DFS
func (g *Graph) DFSRecursive(start string) []string {
visited := make(map[string]bool)
result := []string{}
g.dfsRecursiveHelper(start, visited, &result)
return result
}
func (g *Graph) dfsRecursiveHelper(vertex string, visited map[string]bool, result *[]string) {
visited[vertex] = true
*result = append(*result, vertex)
for _, neighbor := range g.GetNeighbors(vertex) {
if !visited[neighbor] {
g.dfsRecursiveHelper(neighbor, visited, result)
}
}
}
// 8. Graph Algorithms
// HasPath checks if there's a path from start to end
func (g *Graph) HasPath(start, end string) bool {
visited := make(map[string]bool)
queue := []string{start}
visited[start] = true
for len(queue) > 0 {
vertex := queue[0]
queue = queue[1:]
if vertex == end {
return true
}
for _, neighbor := range g.GetNeighbors(vertex) {
if !visited[neighbor] {
visited[neighbor] = true
queue = append(queue, neighbor)
}
}
}
return false
}
// ShortestPath finds shortest path using BFS
func (g *Graph) ShortestPath(start, end string) []string {
if start == end {
return []string{start}
}
// BFS with parent tracking
parent := make(map[string]string)
visited := make(map[string]bool)
queue := []string{start}
visited[start] = true
found := false
for len(queue) > 0 {
vertex := queue[0]
queue = queue[1:]
for _, neighbor := range g.GetNeighbors(vertex) {
if !visited[neighbor] {
visited[neighbor] = true
parent[neighbor] = vertex
queue = append(queue, neighbor)
if neighbor == end {
found = true
break
}
}
}
if found {
break
}
}
if !found {
return []string{}
}
// Reconstruct path
path := []string{end}
current := end
for current != start {
current = parent[current]
path = append([]string{current}, path...)
}
return path
}
// GraphExample demonstrates graph operations
func GraphExample() {
fmt.Println("\n--- Graph Example ---")
// Create undirected graph
g := NewGraph(false)
// Add edges
g.AddEdge("A", "B")
g.AddEdge("A", "C")
g.AddEdge("B", "D")
g.AddEdge("C", "D")
g.AddEdge("D", "E")
fmt.Println("Graph structure:")
fmt.Println(" A -- B")
fmt.Println(" | |")
fmt.Println(" C -- D -- E")
fmt.Printf("\nVertices: %v\n", g.GetVertices())
// Traversals
fmt.Printf("BFS from A: %v\n", g.BFS("A"))
fmt.Printf("DFS from A: %v\n", g.DFS("A"))
fmt.Printf("DFS Recursive from A: %v\n", g.DFSRecursive("A"))
// Path finding
fmt.Printf("Has path A->E: %v\n", g.HasPath("A", "E"))
fmt.Printf("Shortest path A->E: %v\n", g.ShortestPath("A", "E"))
}
// 9. N-ary Tree
// NAryNode represents an n-ary tree node
type NAryNode struct {
Value string
Children []*NAryNode
}
// NewNAryNode creates a new n-ary node
func NewNAryNode(value string) *NAryNode {
return &NAryNode{
Value: value,
Children: []*NAryNode{},
}
}
// AddChild adds a child node
func (n *NAryNode) AddChild(child *NAryNode) {
n.Children = append(n.Children, child)
}
// LevelOrderNAry performs level-order traversal for n-ary tree
func (n *NAryNode) LevelOrderNAry() []string {
if n == nil {
return []string{}
}
result := []string{}
queue := []*NAryNode{n}
for len(queue) > 0 {
current := queue[0]
queue = queue[1:]
result = append(result, current.Value)
for _, child := range current.Children {
queue = append(queue, child)
}
}
return result
}
// NAryTreeExample demonstrates n-ary tree
func NAryTreeExample() {
fmt.Println("\n--- N-ary Tree Example ---")
root := NewNAryNode("Root")
child1 := NewNAryNode("Child1")
child2 := NewNAryNode("Child2")
child3 := NewNAryNode("Child3")
root.AddChild(child1)
root.AddChild(child2)
root.AddChild(child3)
child1.AddChild(NewNAryNode("Grandchild1"))
child1.AddChild(NewNAryNode("Grandchild2"))
child2.AddChild(NewNAryNode("Grandchild3"))
fmt.Println("N-ary Tree structure:")
fmt.Println(" Root")
fmt.Println(" / | \\")
fmt.Println(" c1 c2 c3")
fmt.Println(" / \ \")
fmt.Println(" gc1 gc2 gc3")
fmt.Printf("\nLevelOrder: %v\n", root.LevelOrderNAry())
}
// 10. Trie (Prefix Tree)
// TrieNode represents a trie node
type TrieNode struct {
Children map[rune]*TrieNode
IsEnd bool
}
// NewTrieNode creates a new trie node
func NewTrieNode() *TrieNode {
return &TrieNode{
Children: make(map[rune]*TrieNode),
IsEnd: false,
}
}
// Trie represents a trie
type Trie struct {
Root *TrieNode
}
// NewTrie creates a new trie
func NewTrie() *Trie {
return &Trie{Root: NewTrieNode()}
}
// Insert inserts a word into the trie
func (t *Trie) Insert(word string) {
node := t.Root
for _, char := range word {
if _, exists := node.Children[char]; !exists {
node.Children[char] = NewTrieNode()
}
node = node.Children[char]
}
node.IsEnd = true
}
// Search searches for a word in the trie
func (t *Trie) Search(word string) bool {
node := t.Root
for _, char := range word {
if _, exists := node.Children[char]; !exists {
return false
}
node = node.Children[char]
}
return node.IsEnd
}
// StartsWith checks if any word starts with prefix
func (t *Trie) StartsWith(prefix string) bool {
node := t.Root
for _, char := range prefix {
if _, exists := node.Children[char]; !exists {
return false
}
node = node.Children[char]
}
return true
}
// TrieExample demonstrates trie operations
func TrieExample() {
fmt.Println("\n--- Trie Example ---")
trie := NewTrie()
// Insert words
words := []string{"apple", "app", "application", "banana"}
for _, word := range words {
trie.Insert(word)
fmt.Printf("Inserted: %s\n", word)
}
// Search
fmt.Printf("\nSearch 'app': %v\n", trie.Search("app"))
fmt.Printf("Search 'apple': %v\n", trie.Search("apple"))
fmt.Printf("Search 'apples': %v\n", trie.Search("apples"))
// StartsWith
fmt.Printf("\nStartsWith 'app': %v\n", trie.StartsWith("app"))
fmt.Printf("StartsWith 'ban': %v\n", trie.StartsWith("ban"))
fmt.Printf("StartsWith 'orange': %v\n", trie.StartsWith("orange"))
}
// Main function
func main() {
fmt.Println("=== Web Go Trees and Graphs Examples ===\n")
BinaryTreeExample()
GraphExample()
NAryTreeExample()
TrieExample()
fmt.Println("\n=== All Trees and Graphs Examples Completed ===")
}