Removing an item in a Linked List with Go - go

I want to remove a Node from a linked list in Go, and I have this struct and these methods:
type Node struct {
Next *Node
Val int
}
func (n *Node) Append(val int) {
end := &Node{Val: val}
here := n
for here.Next != nil {
here = here.Next
}
here.Next = end
}
func Remove(n *Node, val int) *Node {
head := n
for head.Next != nil {
if head.Next.Val == val {
head.Next = head.Next.Next
return head
}
head = head.Next
}
return head
}
func NewNode(val int) *Node {
return &Node{Val: val}
}
I want to remove an item like this:
n := NewNode(1)
n.Append(2)
n.Append(3)
n.Append(4)
n.Append(5)
m := Remove(n, 3)
for m != nil {
fmt.Println(n.Val)
m = m.Next
}
The items that get printed out are 3 and 5, not 1,2,4and5`. I re-implemented this code in Python and got the expected answer. What is going on in Go? I have a feeling it has to do something with pointers.

You lose the head from returning a node you use to traverse. Also you are printing out the wrong object
type Node struct {
Next *Node
Val int
}
func (n *Node) Append(val int) {
end := &Node{Val: val}
here := n
for here.Next != nil {
here = here.Next
}
here.Next = end
}
func Remove(n *Node, val int) *Node {
traverser := n
for traverser.Next != nil {
if traverser.Next.Val == val {
traverser.Next = traverser.Next.Next
return n
}
traverser = traverser.Next
}
return n
}
func NewNode(val int) *Node {
return &Node{Val: val}
}
func main() {
n := NewNode(1)
n.Append(2)
n.Append(3)
n.Append(4)
n.Append(5)
m := Remove(n, 3)
for m != nil {
fmt.Println(m.Val)
m = m.Next
}
}

Related

How to check if an element exists in linked list

I am trying to find if an element exists in my linked list so that duplicate elements are not added.
My code follows playground:
package main
import "fmt"
func (e Ensemble) EstVide() bool {
return e.ensemble == nil
}
func (e Ensemble) Card() int {
return e.longueur
}
type Cellule struct {
elem int
suivant *Cellule
}
type Ensemble struct {
ensemble *Cellule
longueur int
}
func (c Cellule) String() string {
if c.suivant == nil {
return fmt.Sprintf("%v}", c.elem)
}
return fmt.Sprintf("%v", c.elem)
}
func (e Ensemble) String() string {
if e.EstVide() {
return ""
}
res := "{"
for curr := e.ensemble; curr != nil; curr = curr.suivant {
res += fmt.Sprintf("%s ", curr)
}
return res[:len(res)-1]
}
func (e Ensemble) Appartient(valeur int) bool {
body := e.String()
for i := 0; i < e.Card(); i++ {
if valeur == int(body[i]) {
return true
}
}
return false
}
func (e *Ensemble) Ajouter(valeur int) {
if !e.Appartient(valeur) {
e.ensemble = &Cellule{elem: valeur, suivant: e.ensemble}
e.longueur++
}
}
func main() {
monEns := Ensemble{}
fmt.Printf("Nb d'éléments dans monEns %v\n", monEns.Card())
fmt.Printf("monEns = %v\n", monEns)
monEns.Ajouter(42)
monEns.Ajouter(10)
monEns.Ajouter(20)
monEns.Ajouter(10)
fmt.Printf("Nb d'éléments dans monEns %v\n", monEns.Card())
fmt.Printf("monEns = %v \n", monEns)
}
The output ({10 20 10 42} includes a duplicate element (10). How can I prevent this?

How to find a binary tree depth using breadth-first algorithm in Golang

I have a binary tree and I would like to find its maximum depth using a breadth-first approach.
I think I am having a logical error in where to increment the depth.
// You can edit this code!
// Click here and start typing.
package main
import (
"log"
"math"
)
type Queue []*Node
func (q *Queue) Enqueue(n *Node) {
*q = append(*q, n)
}
func (q *Queue) Dequeue() *Node {
node := (*q)[0]
*q = (*q)[1:]
return node
}
func (q *Queue) IsEmpty() bool {
return len(*q) == 0
}
type Node struct {
value *int
left *Node
right *Node
}
func (node *Node) insert(value int) {
if node.value == nil {
node.value = &value
return
}
if *node.value <= value {
if node.left == nil {
node.left = &Node{}
}
node.left.insert(value)
return
}
if node.right == nil {
node.right = &Node{}
}
node.right.insert(value)
}
// HELP NEEDED here
func (node *Node) NumberOfVisibleNodes() int {
var counter int
if node == nil || node.value == nil {
return counter
}
hashtable := map[int]int{}
levelDepth := 0
nodeQueue := Queue{node}
for !nodeQueue.IsEmpty() {
currentNode := nodeQueue.Dequeue()
_, found := hashtable[levelDepth]
if !found {
hashtable[levelDepth] = *currentNode.value
}
if currentNode.left != nil {
nodeQueue.Enqueue(currentNode.left)
hashtable[levelDepth+1] = *currentNode.left.value
}
if currentNode.right != nil {
nodeQueue.Enqueue(currentNode.right)
hashtable[levelDepth+1] = *currentNode.right.value
}
levelDepth++
}
return len(hashtable)
}
func (node *Node) NumberOfVisibleNodesRecursively() int {
if node == nil || node.value == nil {
return 0
}
leftMaxDepth := node.left.NumberOfVisibleNodesRecursively()
rightMaxDepth := node.right.NumberOfVisibleNodesRecursively()
maxDepth := math.Max(float64(leftMaxDepth), float64(rightMaxDepth))
return 1 + int(maxDepth)
}
func main() {
testCases := []struct {
expect string
arguments []int
expected int
}{
{
"expect to return 0 when nodes are empty",
[]int{},
0,
},
{
"expect to get 2",
[]int{3, 5},
2,
},
{
"expect to get 3",
[]int{3, 5, 2, 6, 4, 1},
3,
},
{
"expect to return 4",
[]int{3, 5, 2, 6, 4, 1, -10},
4,
},
}
for _, testCase := range testCases {
var tree Node
for _, value := range testCase.arguments {
tree.insert(value)
}
gotResult := tree.NumberOfVisibleNodes()
if gotResult != testCase.expected {
log.Fatalf("%s but got: %d wanted: %d ", testCase.expect, gotResult, testCase.expected)
}
}
}
I wonder if it's even possible. I know the best approach is to use a depth-first approach but I am curious to learn if the breadth approach is possible!
Running code is here: https://go.dev/play/p/exiI-QqRWIM
[UPDATE]
One approach that seems to work is using a tuple.
type TupleQueue []Tuple
func (tq *TupleQueue) Enqueue(t Tuple) {
*tq = append(*tq, t)
}
func (tq *TupleQueue) Dequeue() Tuple {
tuple := (*tq)[0]
*tq = (*tq)[1:]
return tuple
}
func (tq *TupleQueue) IsEmpty() bool {
return len(*tq) == 0
}
func (node *Node) NumberOfVisibleNodes() int {
if node == nil || node.value == nil {
return 0
}
var depth int
tupleQueue := TupleQueue{{depth, node}}
for !tupleQueue.IsEmpty() {
tuple := tupleQueue.Dequeue()
if tuple.level != depth {
depth++
}
if tuple.node.left != nil {
tupleQueue.Enqueue(Tuple{depth + 1, tuple.node.left})
}
if tuple.node.right != nil {
tupleQueue.Enqueue(Tuple{depth + 1, tuple.node.right})
}
}
return depth + 1
}
I wonder if we can do something similar with hashmaps
You don't need tuple or hashmap to do BFS. Just use queue, I show the code below.
func (node *Node) NumberOfVisibleNodes() int {
if node == nil || node.value == nil {
return 0
}
levelDepth := 0
nodeQueue := Queue{node}
for !nodeQueue.IsEmpty() {
tmpQueue := Queue{}
for !nodeQueue.IsEmpty(){
cNode := nodeQueue.Dequeue()
if cNode.right!= nil{
tmpQueue.Enqueue(cNode.right)
}
if cNode.left!= nil{
tmpQueue.Enqueue(cNode.left)
}
}
nodeQueue = tmpQueue
levelDepth++
}
return levelDepth
}

Merging Intervals out of hyphenated string ranges

I have a string like this:
ports := []string{"1", "2-7", "12-1200", "10-500"}
I would like to make an integer set out of this like the output should be :
[]intSet{ 1, 2-7, 10-1200 }
Where intSet is some kind of integer set from which I am able to easily remove and add elements.
Update 1
intSet is a list of sets.
So, 2-7 is also a set.
Update 2
Here the largest set is merged.
e.g.
"1" -> 1
"2-7" -> 2-7
"12-1200" & "10-500" => "10..12.....500....1200" -> 10-1200
Since it's a set so it encompasses a unique range for this, a range which covers the whole set.
package main
import (
"fmt"
"log"
"strconv"
"strings"
)
type intSet struct {
start int
end int
}
func (s intSet) String() string {
if s.start == s.end {
return fmt.Sprintf("%d", s.start)
}
return fmt.Sprintf("%d-%d", s.start, s.end)
}
func (s intSet) in(i int) bool {
return s.start <= i && i <= s.end
}
func (s *intSet) union(set intSet) {
if set.start < s.start {
s.start = set.start
}
if set.end > s.end {
s.end = set.end
}
}
func insert(set intSet, is []intSet) bool {
for i, s := range is {
if s.in(set.start) || s.in(set.end) {
is[i].union(set)
return true
}
//updated here with thankful to #mh-cbon
if set.in(s.start) || set.in(s.end) {
is[i].union(set)
return true
}
}
return false
}
func main() {
var set []intSet
ports := []string{"1", "2-7", "12-1200", "10-500", "9-5500"}
for _, port := range ports {
s := strings.Split(port, `-`)
if len(s) < 1 || len(s) > 2 {
log.Fatalln(`set cannot have multiple values or no value`)
}
start, err := strconv.Atoi(s[0])
if err != nil {
log.Fatalln(err)
}
end := start
if len(s) == 2 {
end, err = strconv.Atoi(s[1])
if err != nil {
log.Fatalln(err)
}
}
temSet := intSet{
start: start,
end: end,
}
if !insert(temSet, set) {
set = append(set, temSet)
}
}
fmt.Println(set) //[1 2-7 9-5500]
}
run here

undefined attributes in an slice of node structs

er, I am trying to learn go by implementing a random graph. I get an error on n.value undefined (type int has no field or method value), and n.neigbours undefined (type int has no field or method neigbours). I can not understand that compilation error as i create a new slice of nodesnr size of empty nodes in the g.nodes = make([]node, g.nodesnr). What is the problem?
package main
import (
"fmt"
//"math/rand"
)
type node struct {
value int
neigbours []int
}
type edge struct {
source int
sink int
}
type graph struct {
nodesnr, edgesnr int
nodes []node
edges chan edge
}
func main() {
randomGraph()
}
func input(tname string) (number int) {
fmt.Println("input a number of " + tname)
fmt.Scan(&number)
return
}
func randomGraph() (g graph) {
g = graph{nodesnr: input("nodes"), edgesnr: input("edges")}
g.addNodes()
for i := 0; i < g.nodesnr; i++ {
fmt.Println(g.nodes[i].value)
}
//g.addEdges()
return
}
func (g *graph) addNodes() {
g.nodes = make([]node, g.nodesnr)
for n := range g.nodes {
n.value = 2
n.neigbours = nil
return
}
}
func (g *graph) addEdges() {
g.edges = make(chan edge)
for i := 0; i < g.edgesnr; i++ {
//g.newEdge()
return
}
}
/*
func (g* graph) newEdge(){
e := new(edge)
e.source, e.sink = rand.Intn(g.nodesnr), rand.Intn(g.nodesnr)
g.edges <-e*
//g.addEdge()
}
*/
func (g *graph) edgeCheck(ep *edge) string {
if ep.source == ep.sink {
return "self"
}
//if(g.neigbourCheck(g.nodes[ep.source].neigbours, ep.sink) OR g.neigbourCheck(g.nodes[ep.sink].neigbours, ep.source){
// return "present"
return "empty"
}
func (g *graph) neigbourCheck(neigbours []node, node int) bool {
for neigbour := range neigbours {
if node == neigbour {
return true
}
}
return false
}
func (g *graph) addEdge() {
e := <-g.edges
switch etype := g.edgeCheck(&e); etype {
case "present":
fallthrough
case "self":
fmt.Println("self")
//go g.newEdge()
case "empty":
//g.nodes[e.source] = append(g.nodes[e.source], e.sink),
//g.nodes[e.sink] = append(g.nodes[e.sink], e.source)
fmt.Println("empty")
default:
fmt.Println("something went wrong")
}
}
Playground
Your error lies on line 47
for n := range g.nodes
When iterating over a slice, when using only one value, that value (n) will be set to the index, which is of type int. What you need to do is to change the line to:
for _, n := range g.nodes
This means that you discard the index but put the value in n instead.
Edit
n will be a copy of the value which means any changes made to n will not affect the node in the slice. To edit the node in the slice, you should actually get the index instead of the value:
for i := range g.nodes {
g.nodes[i].value = 2
g.nodes[i].neigbours = nil
return
}

Compilation error in go program

here is the code and i use gccgo for compilation. this for a graph based organizer. I don't need advise on graph algorithms.
package element
import (
"fmt"
"strings"
"io"
"strconv"
)
type Node struct {
id int
name string
props map[string]string
links map[string][]*Node
}
var names = make(map[string]int , 8)
var nodes = make(map[string][]*Node , 8)
//========functions================
func new_node(Id int) *Node {
return &Node( Id, " ", nil, nil)
}
func getNode_byId(nodes []*Node, id int) *Node {
for _, node := range nodes{
if node.id == id {
return node
}
}
return nil
}
func addNode(store string, node *Node) {
nodes[store] = append(nodes[store], node)
}
func addLinkToNode(node, link *Node, property string) {
node.links[property] = append(node.links[property], link)
}
func nodeFromString(str string, typ string) {
lines := strings.Split(str, "\n")
lcount := len(lines)
if lines[0] == "[begin]" && lines[lcount] == "[end]" {
fmt.Println("common dude! something wrong with ur string")
return
}
fields := strings.Fields(lines[1])
id , _ := strconv.Atoi(fields[1])
nod := getNode_byId(nodes[typ], id )
if nod == nil { nod = new_node(id) }
addNode(typ, nod)
nod.name = typ
lines = lines[2:]
ind :=0
for index, line := range lines {
fields := strings.Fields(line)
if field := fields[0]; field[0] != '-' {
ind = index
break
}
nod.props[fields[0]] = fields[1]
}
lines = lines[ind:]
for index, line := range lines {
if line[0]!= '+' {
ind = index
break
}
pivot := strings.Index(line, " ")
field := line[0:pivot]
fields := strings.Split(line[pivot:], ",")
for _, value := range fields {
id, _ := strconv.Atoi(strings.TrimSpace(value))
var link *Node = getNode_byId(nodes[typ], id)
if link == nil { link = new_node(id) }
addNode(typ, link)
append(nod.links[field], link )
}
}
}
func equal_byId( nodeA, nodeB Node) bool {
return (nodeA.id == nodeB.id)
}
func equal_byProp( nodeA, nodeB Node, property string) bool {
return (nodeA.props[property] == nodeB.props[property])
}
//========methods on node==========
func (node Node) IsEqual_byId( comparand Node ) bool {
return equal_byId(node, comparand)
}
func (node Node) IsEqual_byProp( comparand Node, property string ) bool {
return equal_byProp(node, comparand, property)
}
func (node *Node) addLink (property string, link *Node){
addLinkToNode( node, link, property)
}
//===================
func main() {
fmt.Println("hello world")
}
and this is the error I got, I tried my best but I cannot resolve.
$ gccgo elements.go
elements.go:23:19: error: expected ‘)’
elements.go:23:34: error: expected ‘;’ or ‘}’ or newline
elements.go:23:2: error: too many values in return statement
elements.go:91:4: error: value computed is not used
I do not understand where I need to use the semi-colon and why.
The problem, I think, may be in func new_node:
return &Node( Id, " ", nil, nil)
Should be
return &Node{Id, " ", nil, nil}
See http://golang.org/ref/spec#Composite_literals
Also, I have a feeling that, in func nodeFromString (line 93-ish):
append(nod.links[field], link)
Should be:
nod.links[field] = append(nod.links[field], link)
Otherwise you'll get an error.

Resources