package main import "fmt" func main() { size := 7 table := make([]int, size) for i := range table { table[i] = -1 } keys := []int{10, 22, 31, 4, 15} for _, key := range keys { index := key % size for table[index] != -1 { index = (index + 1) % size } table[index] = key } fmt.Println(table) }
Each key is inserted at index = key % size. If occupied, move to next index until empty.
10 % 7 = 3 → slot 3 empty → insert 10 at 3
22 % 7 = 1 → slot 1 empty → insert 22 at 1
31 % 7 = 3 → slot 3 occupied → move to 4 empty → insert 31 at 4
4 % 7 = 4 → slot 4 occupied → move to 5 empty → insert 4 at 5
15 % 7 = 1 → slot 1 occupied → move to 2 empty → insert 15 at 2
Linear probing places collided keys in the next free slot, which can create long runs of occupied slots called clustering.
package main import "fmt" func insert(table []int, key int) { size := len(table) index := key % size for table[index] != -1 { index = (index + 1) % size } table[index] = key } func main() { table := []int{-1, -1, -1} insert(table, 1) insert(table, 4) insert(table, 7) insert(table, 10) fmt.Println(table) }
The insert function loops until it finds an empty slot. If the table is full, it loops forever causing an infinite loop.
package main import "fmt" func main() { size := 5 table := make([]int, size) for i := range table { table[i] = -1 } keys := []int{1, 6, 11} for _, key := range keys { index := key % size for table[index] != -1 { index = (index + 1) % size } table[index] = key } // Delete key 6 for i := 0; i < size; i++ { if table[i] == 6 { table[i] = -2 // mark deleted break } } fmt.Println(table) }
Key 1 at index 1, key 6 at index 2, key 11 at index 3.
Deleting 6 marks index 2 as -2 (deleted).
Marking deleted slots differently allows the search to continue probing past deleted slots to find keys that may be further down the line.
