package main import "fmt" var headNode Node type Node struct { data string next *Node } func createNode(data string) Node { var node Node node.data = data node.next = nil return node } func insertFirst(value string) { node := createNode(value) tempNode := headNode node.next = &tempNode headNode = node } func insertNode(value string) { newNode := createNode(value) if (headNode == Node {}) { headNode = newNode } else { nextNode := &headNode for nextNode.next != nil { nextNode = nextNode.next } nextNode.next = &newNode } } func deleteFirst() { if (headNode == Node {}) { return } else { headNode = *headNode.next } } func deleteNode(position int) { if (headNode == Node {}) { return } if (position == 0) { headNode = *headNode.next return } node := &headNode for i := 1; node != nil && i < position; i++ { node = node.next } if (node == nil || node.next == nil) { return } next := node.next.next node.next = next } func displayLinkedList() { node := &headNode for node != nil { fmt.Println(node.data) node = node.next } } func main() { insertNode("John") insertNode("Pradeep") insertNode("Andrew") insertNode("Beck") displayLinkedList() deleteNode(1) fmt.Println("--------") displayLinkedList() }
We have seen that a List that is Linked to each other is a Linked List.
Now, we will learn a new term. i.e. Each item in a Linked List is called a Node.
And we can see there are four records in the above Linked List.
Say, for example, the below record is a Node.
So, far we have seen, there were two records in a Node. First record is the actual data or name (In the above example i.e. John). And the second record contains the pointer to the next Node (The second record of John i.e. 9 in the above case was referring to the location of Pradeep).
Even in our Code, we have created a structure called Node.
type Node struct { data string next *Node }
The above structure Node has two attributes :
The first attribute data string is fine. It can hold the name "John" or "Pradeep". But what about the second attribute i.e. next *Node?
Don't you think, the second attribute should have an Integer type variable?So that it can store the pointer to the next Node(i.e. 9 in the above case was referring to the location of Pradeep).
Well ! In this case we are trying something different. i.e. We will let Go decide the next Node.
Sounds Complex ?
Stay with me. Things will become easy with each line.
Let us go to the createNode(...) method.
func createNode(data string) Node { var node Node node.data = data node.next = nil return node }
So, when we create a Node type variable, we simply, pass the data or name(Say "John").
node := createNode("John")
And the createNode(...) method creates a Node type variable for us, with John as the actual data and next as nil. Because it is not referring to any Node type variable yet.
Then the next time, when we create the Node object with Pradeep,
Node node2 = new Node("Pradeep");
We will make node1 object point to node2 by replacing null with node2.
Fair enough !
Now, let us see the Code explanation for Linked List.
So, there are five methods that we have used in the Linked List :
Now, let us see the Linked List in action.
So, in the first line we insert the value John,
insertNode("John");
By using the insertNode(String value) method.
func insertNode(value string) { newNode := createNode(value) if (headNode == Node {}) { headNode = newNode } else { nextNode := &headNode for nextNode.next != nil { nextNode = nextNode.next } nextNode.next = &newNode } }
So, what we are doing in the func insertNode(value string) method is, we are creating a new Node type variable.
newNode := createNode(value)
And as we have seen there is a method func createNode(data string) Node that helps in initialising the values to the Node type variable.
And the below Node object is created.
Now, just remember, we have a variable Node headNode, that always points to the first element in the Linked List. And since, this is the first time we are creating the Linked List. The headNode has to be initialised.
if (headNode == null) { headNode = newNode }
And we don't go to the else part.
Similarly, the next time we try inserting Pradeep.
insertNode("Pradeep");
And the insertNode(value string) method is called.
And the same way, we are creating a new Node type variable.
newNode := createNode(value)
And as we have seen there is a func createNode(...) method that helps in initialising the values to the Node type variable.
And the below Node object is created.
Now since, headNode is not nil
if (headNode == null)
And we come to the else part .
else { nextNode := &headNode for nextNode.next != nil { nextNode = nextNode.next } nextNode.next = &newNode }
In the else part, we create a Node called newNode and initialise it with the address of theheadNode.
nextNode := &headNode
And Since the headNode is the Node where John resides.
We run a for loop to reach the end of the Linked List.
for nextNode.next != nil { nextNode = nextNode.next }
In this case nextNode.next is equal to nil. So, we do not get into the for loop.
And we know newNode contains Pradeep.
And make the nextNode (i.e. The Node containing John) point to newNode.
So, the Linked List is formed with two elements.
Similar way, all the other elements are added to the Linked List.
The next is put as next as the linking will be decided by Go internally.
Now, let us see how do we delete an element from a specific location.
deleteNode(1);
So, we will be deleting the second element as the count starts from 0.
And the deleteNode(position) int method is called,
func deleteNode(position int) { if (headNode == Node {}) { return } if (position == 0) { headNode = *headNode.next return } node := &headNode for i := 1; node != nil && i < position; i++ { node = node.next } if (node == nil || node.next == nil) { return } next := node.next.next node.next = next }
The first if statement checks, if the headNode is nil or not. i.e. If the headNode is nil, then there are no elements in the Linked List. And we stop the execution.
And we check it using an empty structure i.e. Node {}
if (headNode == Node {}) { return }
The next if statement checks, if we are asking to remove the first element.
if (position == 0) { headNode = *headNode.next return }
We initialise the headNode with headNode.next i.e. nil. And the Linked List becomes empty.
If the above two if statement are not satisfied then we come to the next line.
node := &headNode
Where we declare a pointer Node named node and initialise with the address of the headNode Node.
Now since, headNode contains the details of John. node is initialised with John.
Then we run a for loop until we reach a position just before the node that is asked to be deleted.
In this case the second element is asked to be deleted(i.e. 1).
for i := 1; node != nil && i < position; i++ { node = node.next }
So, we exit the for loop, when we are at the second node.
Then we do a check to see if the first node is null or is it not pointing to any element?
if (node == nil || node.next == nil) { return }
If so we stop the execution.
Then we create a Node called next. And initialise the Node with it that contains Andrew.
next := node.next.next
And finally, we make the Node of John point to the Node that contains Andrew.
node.next = next
And we get the Linked List that doesn't have the the second Node. i.e. The node that contained Pradeep.