DEV Community

Shahriyar Al Mustakim Mitul
Shahriyar Al Mustakim Mitul

Posted on

Linked List Part 2

Prepend
We will add a node to starting of a node.

Image description

Case 1:
For empty linked list, we will just add our node and set it to head and tail

Image description
This will turn to this

Image description

Case_2:
For more than 2 nodes, we will just add that and set it to head

Image description
So the code will be:

#Prepend something
    def prepend(self,value):
        new_node=Node(value)
        #when there is empty linked list
        if self.length==0:
            self.head=new_node
            self.tail=new_node
        else: #when there is already nodes and you want to add a node
            new_node.next=self.head
            self.head=new_node
        self.length+=1
        return True
Enter fullscreen mode Exit fullscreen mode

Pop first

Case 1:
If we don't have any item in the list:

Image description

For this, we will check if the length is 0, then returns None

Image description

Case 2:
If we have more than 2 values,

Image description
We will remove the first value

Image description
To remove it we need something to point at it and we will call it temp

Image description

Image description

now, we will remove the head value to next

Image description

Image description
Now, we will remove the head

Image description

Image description
Thus the code will be:

Image description

Case 3:
When we have 1 item in the list.
Image description

Now , we will assign temp to self.head

Image description
Will set head.next to None

Image description
Also we will decrement the list to 0 and also point tail to None

Image description

Image description

So, the real code is:

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None


class LinkedList:
    def __init__(self, value):
        new_node = Node(value)
        self.head = new_node
        self.tail = new_node
        self.length = 1

    def print_list(self):
        temp = self.head
        while temp is not None:
            print(temp.value)
            temp = temp.next

    def append(self, value):
        new_node = Node(value)
        if self.length == 0:
            self.head = new_node
            self.tail = new_node
        else:
            self.tail.next = new_node
            self.tail = new_node
        self.length += 1
        return True

    def pop(self):
        if self.length == 0:
            return None
        temp = self.head
        pre = self.head
        while(temp.next):
            pre = temp
            temp = temp.next
        self.tail = pre
        self.tail.next = None
        self.length -= 1
        if self.length == 0:
            self.head = None
            self.tail = None
        return temp

    def prepend(self, value):
        new_node = Node(value)
        if self.length == 0:
            self.head = new_node
            self.tail = new_node
        else:
            new_node.next = self.head
            self.head = new_node
        self.length += 1
        return True

    #To pop first 
    def pop_first(self):
        #if the list has 0 values
        if self.length == 0:
            return None
        #if the list has more than 2 values or 1 values    
        temp = self.head
        self.head = self.head.next
        temp.next = None
        self.length -= 1
        if self.length == 0:
            self.tail = None
        return temp #to get the node
        #return temp.value : To get the node values


my_linked_list = LinkedList(2)
my_linked_list.append(1)

#As the LinkedIn list has 2,1 & None in the node, if we return temp.value ; we can see that we are getting 2, 1 and then None
# (2) Items - Returns 2 Node
print(my_linked_list.pop_first())
# (1) Item -  Returns 1 Node
print(my_linked_list.pop_first())
# (0) Items - Returns None
print(my_linked_list.pop_first())


Enter fullscreen mode Exit fullscreen mode

Output (Returning the nodes)

Image description

Get
We will get a value from index now. So, to start , we will check the limit of the index if it exceeds or not.
Image description

So, the code will be:

Image description
Now assigning temp to the first value of the list and then looping through it to get the index value:
Image description

So, we will use

Image description
Actually , we use i in the loops when we need to use that i's value inside the loop for example :

for i in range(4):
    print(i)
Enter fullscreen mode Exit fullscreen mode

but here we don't need this because we are not using the value of i. Thus using "_"

When we find our index, we will return it

Image description

So, the code will be

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None


class LinkedList:
    def __init__(self, value):
        new_node = Node(value)
        self.head = new_node
        self.tail = new_node
        self.length = 1

    def print_list(self):
        temp = self.head
        while temp is not None:
            print(temp.value)
            temp = temp.next

    def append(self, value):
        new_node = Node(value)
        if self.length == 0:
            self.head = new_node
            self.tail = new_node
        else:
            self.tail.next = new_node
            self.tail = new_node
        self.length += 1
        return True

    def pop(self):
        if self.length == 0:
            return None
        temp = self.head
        pre = self.head
        while(temp.next):
            pre = temp
            temp = temp.next
        self.tail = pre
        self.tail.next = None
        self.length -= 1
        if self.length == 0:
            self.head = None
            self.tail = None
        return temp

    def prepend(self, value):
        new_node = Node(value)
        if self.length == 0:
            self.head = new_node
            self.tail = new_node
        else:
            new_node.next = self.head
            self.head = new_node
        self.length += 1
        return True

    def pop_first(self):
        if self.length == 0:
            return None
        temp = self.head
        self.head = self.head.next
        temp.next = None
        self.length -= 1
        if self.length == 0:
            self.tail = None
        return temp

    def get(self, index):
        if index < 0 or index >= self.length:
            return None
        temp = self.head
        for _ in range(index):
            temp = temp.next
        return temp# returns the node
        # return temp.value : Returns the value

#Creating a linked List which has value 0,5,4,3,None
my_linked_list = LinkedList(0)
my_linked_list.append(5)
my_linked_list.append(4)
my_linked_list.append(3)

#Looking for value 2 in the linked List and will return the node
print(my_linked_list.get(2))


Enter fullscreen mode Exit fullscreen mode

Output:

Image description

Returns the node where it finds the index 2's node

Set value

Assume that we have a list which has 11,3,23,7 and you want to change the index 1 to 4 instead of 3.
Now, you can use the get method and look if that index 1 exists or not. If it exists, it will go into it and change the temp value to temp . Ultimately making 3 to 4 and return True

Image description
Image description

Thus the code will be:

Image description

The code is

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None


class LinkedList:
    def __init__(self, value):
        new_node = Node(value)
        self.head = new_node
        self.tail = new_node
        self.length = 1

    def print_list(self):
        temp = self.head
        while temp is not None:
            print(temp.value)
            temp = temp.next

    def append(self, value):
        new_node = Node(value)
        if self.length == 0:
            self.head = new_node
            self.tail = new_node
        else:
            self.tail.next = new_node
            self.tail = new_node
        self.length += 1
        return True

    def pop(self):
        if self.length == 0:
            return None
        temp = self.head
        pre = self.head
        while(temp.next):
            pre = temp
            temp = temp.next
        self.tail = pre
        self.tail.next = None
        self.length -= 1
        if self.length == 0:
            self.head = None
            self.tail = None
        return temp

    def prepend(self, value):
        new_node = Node(value)
        if self.length == 0:
            self.head = new_node
            self.tail = new_node
        else:
            new_node.next = self.head
            self.head = new_node
        self.length += 1
        return True

    def pop_first(self):
        if self.length == 0:
            return None
        temp = self.head
        self.head = self.head.next
        temp.next = None
        self.length -= 1
        if self.length == 0:
            self.tail = None
        return temp

    def get(self, index):
        if index < 0 or index >= self.length:
            return None
        temp = self.head
        for _ in range(index):
            temp = temp.next
        return temp

    def set_value(self, index, value):
        temp = self.get(index)
        if temp:
            temp.value = value
            return True
        return False

#A linked list having 11,3,23 and 7
my_linked_list = LinkedList(11)
my_linked_list.append(3)
my_linked_list.append(23)
my_linked_list.append(7)

#changing the index 1 value to 4 instead of 3
my_linked_list.set_value(1,4)

my_linked_list.print_list() #printing the e whole list
Enter fullscreen mode Exit fullscreen mode

Output:
Image description

Insert
In a particular index, we will add a node.
Image description
Firstly, we will check the index where we want to send is within the range or not .
Case 1:
Secondly, if we want to add the node 4 at the beginning of the list, it is prepending.
Case 2:
Again,if we want to add it to the end of the list , it is append
Image description

case 3:
If we have to insert the node within the list,

Image description
Assuming that we want to insert node 4, in index 2. So, we will set a temp in index 1.

Image description
We will point the temp.next as the node and node.next as the index 2 value which is 23.

Image description
Image description
So, the code for this change

Image description
Again, the code for this change
Image descriptionImage description

Thus it is:
Image description
So, the overall code will be:

Image description

Lets do the coding
We will turn this
Image description
to this
Image description

the code:

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None


class LinkedList:
    def __init__(self, value):
        new_node = Node(value)
        self.head = new_node
        self.tail = new_node
        self.length = 1

    def print_list(self):
        temp = self.head
        while temp is not None:
            print(temp.value)
            temp = temp.next

    def append(self, value):
        new_node = Node(value)
        if self.length == 0:
            self.head = new_node
            self.tail = new_node
        else:
            self.tail.next = new_node
            self.tail = new_node
        self.length += 1
        return True

    def pop(self):
        if self.length == 0:
            return None
        temp = self.head
        pre = self.head
        while(temp.next):
            pre = temp
            temp = temp.next
        self.tail = pre
        self.tail.next = None
        self.length -= 1
        if self.length == 0:
            self.head = None
            self.tail = None
        return temp

    def prepend(self, value):
        new_node = Node(value)
        if self.length == 0:
            self.head = new_node
            self.tail = new_node
        else:
            new_node.next = self.head
            self.head = new_node
        self.length += 1
        return True

    def pop_first(self):
        if self.length == 0:
            return None
        temp = self.head
        self.head = self.head.next
        temp.next = None
        self.length -= 1
        if self.length == 0:
            self.tail = None
        return temp

    def get(self, index):
        if index < 0 or index >= self.length:
            return None
        temp = self.head
        for _ in range(index):
            temp = temp.next
        return temp

    def set_value(self, index, value):
        temp = self.get(index)
        if temp:
            temp.value = value
            return True
        return False

    def insert(self, index, value):
        if index < 0 or index > self.length:
            return False #if the insert method fails
        if index == 0:
            return self.prepend(value)
        if index == self.length:
            return self.append(value)
        new_node = Node(value)
        temp = self.get(index - 1)
        new_node.next = temp.next
        temp.next = new_node
        self.length += 1   
        return True  #if the insert method passes

# linked list having value 0 & 2
my_linked_list = LinkedList(0)
my_linked_list.append(2)

#insert value 1 in index 1
my_linked_list.insert(1,1)

my_linked_list.print_list()

Enter fullscreen mode Exit fullscreen mode

Remove
Note: None is opposite of returning a node
True is opposite of returning False
Case 1:
Lets remove the index 1's node

Image description
Case 2:
To remove the last item
Image description
Case 3:
To remove something from middle. Assume we will remove index no 2

Image description
We are going to assign prev and temp to indexes

Image description
Because when you remove the temp value, you need something to add that to the other part

Image description
We will set prev and next by this:

Image description

So, this is how things are going to work

Image description

Image description

Image description

Image description

So, lets remove the index 2 from this list

and Image description
make it this

Image description
Code:

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None


class LinkedList:
    def __init__(self, value):
        new_node = Node(value)
        self.head = new_node
        self.tail = new_node
        self.length = 1

    def print_list(self):
        temp = self.head
        while temp is not None:
            print(temp.value)
            temp = temp.next

    def append(self, value):
        new_node = Node(value)
        if self.length == 0:
            self.head = new_node
            self.tail = new_node
        else:
            self.tail.next = new_node
            self.tail = new_node
        self.length += 1
        return True

    def pop(self):
        if self.length == 0:
            return None
        temp = self.head
        pre = self.head
        while(temp.next):
            pre = temp
            temp = temp.next
        self.tail = pre
        self.tail.next = None
        self.length -= 1
        if self.length == 0:
            self.head = None
            self.tail = None
        return temp

    def prepend(self, value):
        new_node = Node(value)
        if self.length == 0:
            self.head = new_node
            self.tail = new_node
        else:
            new_node.next = self.head
            self.head = new_node
        self.length += 1
        return True

    def pop_first(self):
        if self.length == 0:
            return None
        temp = self.head
        self.head = self.head.next
        temp.next = None
        self.length -= 1
        if self.length == 0:
            self.tail = None
        return temp

    def get(self, index):
        if index < 0 or index >= self.length:
            return None
        temp = self.head
        for _ in range(index):
            temp = temp.next
        return temp

    def set_value(self, index, value):
        temp = self.get(index)
        if temp:
            temp.value = value
            return True
        return False

    def insert(self, index, value):
        if index < 0 or index > self.length:
            return False
        if index == 0:
            return self.prepend(value)
        if index == self.length:
            return self.append(value)
        new_node = Node(value)
        temp = self.get(index - 1)
        new_node.next = temp.next
        temp.next = new_node
        self.length += 1   
        return True  

    def remove(self, index):
        #checking if the index exists or not
        if index < 0 or index >= self.length:
            return None
        #if need to remove the first index Case 1   
        if index == 0:
            return self.pop_first()
        #if need to remove the last index    Case 2
        if index == self.length - 1:
            return self.pop()
        #if need to remove in the middle    Case 3 
        pre = self.get(index - 1)
        temp = pre.next
        pre.next = temp.next
        temp.next = None
        self.length -= 1
        return temp

#Creating a list of 11,2,23,7
my_linked_list = LinkedList(11)
my_linked_list.append(3)
my_linked_list.append(23)
my_linked_list.append(7)

#removing the index 2
print(my_linked_list.remove(2))

my_linked_list.print_list()

Enter fullscreen mode Exit fullscreen mode

Reverse

Note: Very important for interview
We are going to make this

Image description
to

Image description
Image description
Image description
Image description
Image description

So,we will switch head and tail
Image description
Image description
Image description
So, the codes for this

Image description
Now we are going to assign before & after

TImage description
hey will iterate and make it reversed

Image description
Lets iterate through

Image description

Image description
and now the important one

ThImage description
this change flips temp.next to before . So, 1 flip done

Image description

Image description

Image description

So, 1 iteration is done and this is how it will flip all the way

Image description
Image description

Image description

Image description
So, again the iteration is done and thus total list will be reversed

For the last one,

Image description

Image description
Image description
Image description

Image description
Image description
Image description

Done!
Let's reverse it

Image description

to
Image description

Code

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None


class LinkedList:
    def __init__(self, value):
        new_node = Node(value)
        self.head = new_node
        self.tail = new_node
        self.length = 1

    def print_list(self):
        temp = self.head
        while temp is not None:
            print(temp.value)
            temp = temp.next

    def append(self, value):
        new_node = Node(value)
        if self.length == 0:
            self.head = new_node
            self.tail = new_node
        else:
            self.tail.next = new_node
            self.tail = new_node
        self.length += 1
        return True

    def pop(self):
        if self.length == 0:
            return None
        temp = self.head
        pre = self.head
        while(temp.next):
            pre = temp
            temp = temp.next
        self.tail = pre
        self.tail.next = None
        self.length -= 1
        if self.length == 0:
            self.head = None
            self.tail = None
        return temp

    def prepend(self, value):
        new_node = Node(value)
        if self.length == 0:
            self.head = new_node
            self.tail = new_node
        else:
            new_node.next = self.head
            self.head = new_node
        self.length += 1
        return True

    def pop_first(self):
        if self.length == 0:
            return None
        temp = self.head
        self.head = self.head.next
        temp.next = None
        self.length -= 1
        if self.length == 0:
            self.tail = None
        return temp

    def get(self, index):
        if index < 0 or index >= self.length:
            return None
        temp = self.head
        for _ in range(index):
            temp = temp.next
        return temp

    def set_value(self, index, value):
        temp = self.get(index)
        if temp:
            temp.value = value
            return True
        return False

    def insert(self, index, value):
        if index < 0 or index > self.length:
            return False
        if index == 0:
            return self.prepend(value)
        if index == self.length:
            return self.append(value)
        new_node = Node(value)
        temp = self.get(index - 1)
        new_node.next = temp.next
        temp.next = new_node
        self.length += 1   
        return True  

    def remove(self, index):
        if index < 0 or index >= self.length:
            return None
        if index == 0:
            return self.pop_first()
        if index == self.length - 1:
            return self.pop()
        pre = self.get(index - 1)
        temp = pre.next
        pre.next = temp.next
        temp.next = None
        self.length -= 1
        return temp

    def reverse(self):
        #switching  head and tail
        temp = self.head
        self.head = self.tail
        self.tail = temp
        after = temp.next
        before = None

        #reversing 
        for _ in range(self.length):
            after = temp.next
            temp.next = before
            before = temp
            temp = after

#Created a linked List of 1,2,3,4
my_linked_list = LinkedList(1)
my_linked_list.append(2)
my_linked_list.append(3)
my_linked_list.append(4)

#making it reversed
my_linked_list.reverse()

my_linked_list.print_list()
Enter fullscreen mode Exit fullscreen mode

Output
Image description

Top comments (0)