Missed Print Line - python

I am trying to print the program so it will look like this.
Inserting 1
Inserting 2
Inserting 3
Top element is 3
Removing 3
Removing 2
Removing 1
The stack is empty
But when I run the program, I missed "Inserting 1".
My code look like this
class Node:
def __init__(self,data):
self.data = data
self.next = None
class Stack:
def __init__(self):
self.head = None
def isempty(self):
if self.head == None:
return True
else:
return False
def push(self,data):
if self.head == None:
self.head=Node(data)
else:
newnode = Node(data)
newnode.next = self.head
self.head = newnode
print("Inserting ", str(self.head.data))
def pop(self):
if self.isempty():
return None
else:
poppednode = self.head
self.head = self.head.next
poppednode.next = None
print("Removing",poppednode.data)
return poppednode.data
def peek(self):
if self.isempty():
return None
else:
return self.head.data
def display(self):
iternode = self.head
if self.isempty():
print("The stack is empty")
else:
while(iternode != None):
print(iternode.data,"->",end = "")
iternode = iternode.next
return
stack = Stack()
stack.push(1)
stack.push(2)
stack.push(3)
print("Top element is ",stack.peek())
stack.pop()
stack.pop()
stack.pop()
stack.display()

First time you push an item, self.head is None so the first block of code is executed. Unindent the print('Insert') line so it prints for both cases.
def push(self,data):
if self.head == None:
self.head = Node(data)
else:
newnode = Node(data)
newnode.next = self.head
self.head = newnode
print("Inserting ", str(self.head.data)) # <== unindent 1-level

When you are pushing the first time self.head will be None and it won't go in the else condition where it is printing "Inserting 1"

Related

pop method LinkedList Class

I have implemented the LinkedList class: I need to implement the pop() which takes no parameter. The method removes and returns the item at the end of the linked list. If the list is empty it returns None and does nothing.
class LinkedList:
def __init__(self):
self.head = None
self.count = 0
def is_empty(self):
return self.count == 0
def size(self):
return self.count
def add(self, item):
new_node = Node(item)
new_node.set_next(self.head)
self.head = new_node
self.count += 1
def search(self, item):
current = self.head
while current != None:
if current.get_data() == item:
return True
else:
current = current.get_next()
return False
def remove(self, item):
found = False
current = self.head
previous = None
while current != None and not found:
if current.get_data() == item:
found = True
else:
previous = current
current = current.get_next()
if found:
if previous == None:
self.head = current.get_next()
else:
previous.set_next(current.get_next())
self.count -= 1
else:
raise ValueError("remove(" + str(item) + "). " + str(item) + " is not in list")
def clear(self):
self.head = None
self.count = 0
def __str__(self):
temp = self.head
if(temp != None):
output ="Head"
while (temp != None):
output = output+" --> "+str(temp.data)
temp = temp.next
return output
else:
return "Head --> None"
def append(self, item):
new_node = Node(item)
if self.head is None:
self.head = new_node
return
last = self.head
while(last.next):
last = last.next
last.next = new_node
def pop(self): #Problem here
if self.head is None:
return None
else:
popnode = self.head
self.head = self.head.next
popnode.next = None
return popnode.data
Test:
a_list = LinkedList()
a_list.add(1)
a_list.add(2)
a_list.add(3)
print(a_list)
print("Removed item:",a_list.pop())
print("Removed item:",a_list.pop())
print(a_list)
Expected Output:
Head --> 3 --> 2 --> 1
Removed item: 1
Removed item: 2
Head --> 3
Recd Output:
Head --> 3 --> 2 --> 1
Removed item: 3
Removed item: 2
Head --> 1
Test:
a_list = LinkedList()
a_list.append(1)
a_list.append(2)
a_list.append(3)
print(a_list)
print("Removed item:",a_list.pop())
print("Removed item:",a_list.pop())
print(a_list)
Expected output:
Head --> 1 --> 2 --> 3
Removed item: 3
Removed item: 2
Head --> 1
Recd output:
Head --> 1 --> 2 --> 3
Removed item: 1
Removed item: 2
Head --> 3
Here's a simplified pop() method which does what you require -
def pop(self): #Problem here
# Empty LinkedList
if self.head is None:
return None
# There is a single node in the LinkedList = head, read data and delete it
if self.head.next is None:
data = self.head.data
self.head = None
return data
# there are 2 or more nodes in the LinkedList
secondlast = self.head
while (secondlast.next.next):
secondlast = secondlast.next
# found the second last node
# read the data of the last node and then delete it, by setting secondlast.next = None
data = secondlast.next.data
secondlast.next = None
return data
another approach using a temporary dummy node to simplify case when there is a single node in the LinkedList-
def pop(self): #Problem here
# Empty linkedlist
if self.head is None:
return None
# create a dummy secondlast node
secondlast = Node(-1)
secondlast.next = self.head
while (secondlast.next.next):
secondlast = secondlast.next
data = secondlast.next.data
secondlast.next = None
return data
In your LinkedList, both append() and pop() methods are O(n), since you need to traverse through whole LinkedList to do those operations. Consider adding a new property self.tail(or self.secondlast) to the LinkedList which keeps track of the last node in the LinkedList. It would help in simplifying the code and making both append() and pop() operations O(1)
Just track popnode.next when become None and at the same time store previous item, when popnode.next become None, Just put next of prev None, and return data of popnode.next:
def pop(self): # Problem here
if self.head is None:
return None
elif self.head.next == None:
d = self.head.data
self.head = None
return d
else:
popnode = self.head
prev = popnode
while popnode.next:
prev = popnode
popnode = popnode.next
prev.next = None
return popnode.data
The output of:
a_list = LinkedList()
a_list.add(1)
a_list.add(2)
a_list.add(3)
print(a_list)
print("Removed item:", a_list.pop())
print("Removed item:", a_list.pop())
print("Removed item:", a_list.pop())
print(a_list)
Will be:
Head --> 3--> 2--> 1
Removed item: 1
Removed item: 2
Removed item: 3
Head None

How to fix errors in singly linked list method append

I have two class a node and a linked. My error is coming from the append method located in the linkedList class.
I try to .append(10) but it does not print the 10 out only the 5 when it should be appending to the end. By chance can anyone see the error?
class Node:
def __init__(self, data):
self.data = data
self.next = None
class linkedList:
def __init__(self):
self.head = None
def append(self, data):
newNode = Node(data)
if self.head == None:
self.head = newNode
return
else:
lastNode = self.head
while lastNode.next != None:
lastNode = lastNode.next
lastNode.next = newNode
def prepend(self, data):
newNode = Node(data)
if self.head == None:
self.head = newNode
return
else:
newNode.next = self.head
self.head = newNode
def insertAfterNode(self, prevNode, data):
newNode = Node(data)
newNode.next = prevNode.next
prevNode.next = newNode
def printList(self):
curNode = self.head
while curNode.next != None:
print(curNode.data)
curNode = curNode.next
def deleteNode(self, key):
curNode = self.head
if curNode != None and curNode.data == key:
self.head = curNode.next
curNode = None
return
else:
prev = None
while curNode != None and curNode.data != key:
prev = curNode
curNode = curNode.next
if curNode == None:
print("The data is not found in the list")
return
else:
prev.next = curNode.next
curNode = None
# Testing the Linked List
linkedLst = linkedList()
linkedLst.append(5)
linkedLst.append(10)
linkedLst.printList()
linkedLst.prepend(15)
linkedLst.printList()
linkedLst.insertAfterNode(linkedLst.head.next, 6)
linkedLst.insertAfterNode(linkedLst.head.next.next, 8)
linkedLst.printList()
linkedLst.deleteNode(6)
linkedLst.deleteNode(20)
linkedLst.printList()
Expected result should be 5 10, 15 5 10, 15 6 8 5 10, 15 8 5 10, and then an error message saying it can not be deleted.
However, I am getting 5, 15 5, 15 6 8 5, 15 8 5 and it excludes the 10.
I am running on vim and have python 3.7.4
If you look at method printList, the while loop stops when curNode.next is None which is when curNode is the last node. The last node didn't get a change to be printed. The element 10 is there, it's just not getting printed.
Also, just a minor thing, it's good practice to use CapWords for class names so your code is consistent with the recommended style guide.

Double Linked List Middle Insert doesn't work

import math
class Node:
def __init__(self, val, next = None, prev = None):
self.data = val
self.next = next
self.prev = prev
class LinkedList:
def __init__(self):
self.head = None
self.tail = None
self.count = 0
def StartInsert(self, val):
newNode = Node(val)
if self.count == 0:
self.head = newNode
self.tail = newNode
else:
self.head.prev = newNode
newNode.next = self.head
self.head = newNode
self.count += 1
def EndInsert(self, val):
newNode = Node(val)
if self.count == 0:
self.head = newNode
self.tail = newNode
else:
self.tail.next = newNode
newNode.prev = self.tail
self.tail = newNode
self.count += 1
def MiddleInsert(self, val):
newNode = Node(val)
if self.count == 0:
self.head = newNode
self.tail = newNode
else:
index = math.ceil(self.count/2)-1
temp = self.head
while index > 0:
temp = temp.next
index -= 1
temp.next = Node(val, temp.next)
temp.prev = Node(temp.prev.data, temp)
self.count +=1
def delete(self, val):
curNode = self.head
while curNode != None:
if curNode.data == val:
if curNode.prev != None:
curNode.prev.next = curNode.next
else:
self.head = curNode.next
if curNode.next != None:
curNode.next.prev = curNode.prev
else:
self.tail = curNode.prev
self.count -= 1
curNode = curNode.next
def reverse(self):
temp = None
current = self.head
while current != None:
temp = current.prev
current.prev = current.next
current.next = temp
current = current.prev
if temp:
self.head = temp.prev
self.tail = temp.next
def traverse(self):
s = ""
p = self.head
while p is not None:
s += str(p.data) + ' ';
p = p.next
print(s + "| count: " + str(self.count))
list = LinkedList()
list.EndInsert("a")
list.StartInsert("b")
list.StartInsert("c")
list.EndInsert("d")
list.MiddleInsert("c")
list.traverse()
list.reverse()
list.traverse()
Middle Insert gives correct return but doesn't stop. I did the same method for singly linked list but it doesn't seem to work properly for double linked list. It returns proper value but keep getting stuck at the while loop.
I am trying to figure how to connect the newNode(). Please help me by showing code and the reason I get such error.
Thank you so much for helping.
An initial error is that you are creating more Node that necessarily in your MiddleInsert method.
This can lead you to finding the error in your code.
After removing these extra creations, you should simply switch the prev and next pointers, checking that the temp is not actually the last element:
def MiddleInsert(self, val):
newNode = Node(val)
if self.count == 0:
self.head = newNode
self.tail = newNode
else:
index = math.ceil(self.count/2)-1
temp = self.head
while index > 0:
temp = temp.next
index -= 1
newNode.next = temp.next
temp.next = newNode
newNode.prev = temp
if newNode.next is not None:
newNode.next.prev = newNode
self.count +=1
In a doubly linked list, you must maintain prev and next pointers. In MiddleInsert, once you have selected the element that you want to add the new node after, you must insert the new element between that one and its follower.
Let us call C the new node, A the selected node and say B=A.next. Before insertion, you have A.next == B and B.prev == A ; after insertion, you want to have
A.next == C, C.prev == A, C.next == B and B.prev == C.
Just write that in MiddleInsert (unrelated, but no need for the math module here, and for ... in range(...) is the Pythonic way for counting loops):
def MiddleInsert(self, val):
newNode = Node(val)
if self.count == 0:
self.head = newNode
self.tail = newNode
elif self.count == 1:
self.tail = newNode
self.head.next = newNode
newNode.prev = self.head
else:
index = (self.count-1) // 2
temp = self.head
for i in range(index):
temp = temp.next
temp.next.prev = newNode
newNode.next = temp.next
newNode.prev = temp
temp.next = newNode
self.count +=1

double linked list reverse function doesn't work

Everything else works except for the reverse function. The while loop doesn't end. I add in more details. Im so sorry. This is my second time getting help from Stack overflow.
This is the full code. Im not sure how to send the tail for reverse function.
Thank you so much. I truly appreciate all of your help.
import math
class Node:
def __init__(self, val, next = None, prev = None):
self.data = val
self.next = next
self.prev = prev
class LinkedList:
def __init__(self):
self.head = None
self.tail = None
self.count = 0
def StartInsert(self, val):
newNode = Node(val)
if self.count == 0:
self.head = newNode
self.tail = newNode
else:
self.head.prev = newNode
newNode.next = self.head
self.head = newNode
self.count += 1
def EndInsert(self, val):
newNode = Node(val)
if self.count == 0:
self.head = newNode
self.tail = newNode
else:
self.tail.next = newNode
newNode.prev = self.tail
self.tail = newNode
self.count += 1
def MiddleInsert(self, val):
newNode = Node(val)
if self.count == 0:
self.head = newNode
self.tail = newNode
else:
index = math.ceil(self.count/2)
temp = self.head
while index > 0:
temp = temp.next
index =- 1
temp.next = Node(val, temp.next)
temp.prev = Node(temp.prev.data, temp)
self.count +=1
def search(self, val):
p = self.head
while p is not None:
if p.data == val:
return p
p = p.next
def delete(self, val):
curNode = self.head
while curNode != None:
if curNode.data == val:
if curNode.prev != None:
curNode.prev.next = curNode.next
else:
self.head = curNode.next
if curNode.next != None:
curNode.next.prev = curNode.prev
else:
self.tail = curNode.prev
self.count -= 1
curNode = curNode.next
def reverse(self):
temp = None
current = self.head
while current != None:
temp = current.prev
current.prev = current.next
current.next = temp
current = current.prev
if temp:
self.head = temp.prev
self.tail=
def traverse(self):
s = ""
p = self.head
while p is not None:
s += str(p.data) + ' ';
p = p.next
print(s + "| count: " + str(self.count))
list = LinkedList()
list.EndInsert("a")
list.StartInsert("b")
list.StartInsert("c")
list.EndInsert("d")
list.MiddleInsert("c")
list.traverse()
print("_________________")
list.reverse()
list.traverse()

Node getting added twice into list

This is my code ignore if any of the spacing is wrong the code works perfectly fine in python.
class Node:
def __init__(self, value):
self.value = value
self.next = None
def __str__(self):
return "Node({})".format(self.value)
def getNext(self):
return self.next
def getValue(self):
return self.value
def setNext(self, new_next):
self.next = new_next
def setValue(self, new_value):
self.value = new_value
__repr__ = __str__
class OrderedLinkedList:
def __init__(self):
self.head=None
self.tail=None
self.count = 0
def __str__(self):
temp=self.head
out=[]
while temp:
out.append(str(temp.value))
temp=temp.next
out=' '.join(out)
return ('Head:{}\nTail:{}\nList:{}'.format(self.head,self.tail,out))
__repr__=__str__
def add(self, value):
#write your code here
if self.head == None:
new_node = Node(value)
self.head = new_node
self.tail = self.head
self.head.setNext(self.tail)
if self.head.value > value:
new_node = Node(value)
new_node.value = value
new_node.next = self.head
self.head = new_node
else:
new_node = Node(value)
self.tail.setNext(new_node)
self.tail = new_node
self.count += 1
def pop(self):
#write your code here
if self.head == None:
return 'List is empty'
if len(self) == 1:
value = self.head.getValue()
self.head = None
self.tail = None
self.count = 0
return value
current = self.head
while current.next is not self.tail:
current = current.getNext()
value = self.tail.getValue()
self.tail = current
self.tail.next = None
self.count -= 1
return value
def isEmpty(self):
#write your code here
return self.head == None
def __len__(self):
#write your code here
return self.count
The only problem I have with it is that when I first use the function add it adds the number twice. Below is the outcome when I first call add every time after that it adds the number only once. How can I fix it so it only adds the first number once instead of twice.
>>> x=OrderedLinkedList()
>>> x.add(2)
>>> print(x)
Head:Node(2)
Tail:Node(2)
List:2 2
add(item) adds a new Node with value=item to the list making sure that the ascending order is preserved. It needs the item and returns nothing.
Yep, it adds the first number twice since you need fix a bug in your add method by adding an elif:
def add(self, value):
if self.head == None:
new_node = Node(value)
self.head = new_node
self.tail = self.head
# self.head.setNext(self.tail) ## remove to prevent infinity loop
elif self.head.value > value:
new_node = Node(value)
new_node.value = value
new_node.next = self.head
self.head = new_node
else:
new_node = Node(value)
self.tail.setNext(new_node)
self.tail = new_node
Since, if the head es None once the data is added then the next conditional always will execute one of the two parts on if or else.

Categories

Resources