I'm trying to construct a Queue linked list using only a head pointer (no tail).
but i cant seem to enqueue at the end of the list.
example: at the moment the code will: c -> b -> a, however i would like reverse it a -> b -> c.
class Node:
'''A node for a linked list.'''
def __init__(self, initdata):
self.data = initdata
self.next = None
class Queue(object):
def __init__(self):
self.head = None
def enqueue(self, item):
"""Add an item onto the tail of the queue."""
if self.head == None:
temp = Node(item)
temp.next = self.head
self.head = temp
else:
current = self.head
while current != None:
current = current.next
if current == None:
temp = Node(item)
temp.next = current
current = temp
def dequeue(self):
if self.head == None:
raise IndexError("Can't dequeue from empty queue.")
else:
current_first = self.head
current = self.head.next
return current_first.data
This should do it:
class Node:
'''A node for a linked list.'''
def __init__(self, initdata):
self.data = initdata
self.next = None
class Queue(object):
def __init__(self):
self.head = None
def enqueue(self, item):
"""Add an item onto the tail of the queue."""
if self.head is None:
self.head = Node(item)
else:
current = self.head
while current.next is not None:
current = current.next
current.next = Node(item)
def dequeue(self):
if self.head is None:
raise IndexError("Can't dequeue from empty queue.")
else:
first = self.head
self.head = self.head.next
return first.data
Besides some logic fixes (we need to create a new node and store it in current.next, current is just a variable pointing to a node), note we use is operator for testing for None and Node constructor to set data (so we can create and assign new nodes without temp var).
For example:
q = Queue()
q.enqueue('a')
q.enqueue('b')
q.enqueue('c')
print(q.dequeue())
print(q.dequeue())
print(q.dequeue())
Outputs:
a
b
c
Btw, note that such structure requires O(N) insertion time and O(1) deletion (pop) time. Double-ended queue (like the standard collections.deque) will do both insertion and deletion in constant time.
Related
why can't print reversed this double linked list by python?
always print 6 or None
please can anyone help me fast to pass this task
///////////////////////////////////////////////////////////////////////////
class Node:
def __init__(self, data=None, next=None, prev=None):
self.data = data
self.next = next
self.previous = prev
sample methods==>
def set_data(self, newData):
self.data = newData
def get_data(self):
return self.data
def set_next(self, newNext):
self.next = newNext
def get_next(self):
return self.next
def hasNext(self):
return self.next is not None
def set_previous(self, newprev):
self.previous = newprev
def get_previous(self):
return self.previous
def hasPrevious(self):
return self.previous is not None
class double===>
class DoubleLinkedList:
def __init__(self):
self.head = None
self.tail = None
def addAtStart(self, item):
newNode = Node(item)
if self.head is None:
self.head = self.tail = newNode
else:
newNode.set_next(self.head)
newNode.set_previous(None)
self.head.set_previous(newNode)
self.head = newNode
def size(self):
current = self.head
count = 0
while current is not None:
count += 1
current = current.get_next()
return count
here is the wrong method ==>
try to fix it without more changes
def printReverse(self):
current = self.head
while current:
temp = current.next
current.next = current.previous
current.previous = temp
current = current.previous
temp = self.head
self.head = self.tail
self.tail = temp
print("Nodes of doubly linked list reversed: ")
while current is not None:
print(current.data),
current = current.get_next()
call methods==>
new = DoubleLinkedList()
new.addAtStart(1)
new.addAtStart(2)
new.addAtStart(3)
new.printReverse()
Your printReverse seems to do something else than what its name suggests. I would think that this function would just iterate the list nodes in reversed order and print the values, but it actually reverses the list, and doesn't print the result because of a bug.
The error in your code is that the final loop has a condition that is guaranteed to be false. current is always None when it reaches that loop, so nothing gets printed there. This is easily fixed by initialising current just before the loop with:
current = self.head
That fixes your issue, but it is not nice to have a function that both reverses the list, and prints it. It is better practice to separate these two tasks. The method that reverses the list could be named reverse. Then add another method that allows iteration of the values in the list. This is done by defining __iter__. The caller can then easily print the list with that iterator.
Here is how that looks:
def reverse(self):
current = self.head
while current:
current.previous, current.next = current.next, current.previous
current = current.previous
self.head, self.tail = self.tail, self.head
def __iter__(self):
node = self.head
while node:
yield node.data
node = node.next
def __repr__(self):
return "->".join(map(repr, self))
The main program can then be:
lst = DoubleLinkedList()
lst.addAtStart(1)
lst.addAtStart(2)
lst.addAtStart(3)
print(lst)
lst.reverse()
print(lst)
I am creating a Linked List implementation and I cannot fix this error of having to double call node.val.val to print the data instead of the memory address.
Here is my implementation:
class LinkedNode:
def __init__(self, val, nxt=None):
self.val = val
self.nxt = nxt
class LinkedList:
def __init__(self, head=None):
self.head = head
def append(self, new_val):
node = LinkedNode(new_val, None)
if self.head:
curr = self.head
while curr.nxt:
curr = curr.nxt
curr.nxt = node
else:
self.head = node
def print(self):
curr = self.head
while curr:
**print(curr.val)**
curr = curr.nxt
l1 = LinkedList()
l1.append(LinkedNode(2))
l1.append(LinkedNode(3))
l1.append(LinkedNode(4))
l1.print()
When the line in the print function is "print(curr.val)", the function prints memory addresses. When the line is "print(curr.val.val)", the function prints 2,3,4.
Does anyone have a possible solution?
You were passing a LinkedNode() object as an argument to .append() function:
class LinkedNode:
def __init__(self, value, nxt=None):
self.val = value
self.nxt = nxt
class LinkedList:
def __init__(self, head=None):
self.head = head
def append(self, new_val):
node = LinkedNode(new_val, None) #Creation of LinkedNode from integer
if self.head:
curr = self.head
while curr.nxt:
curr = curr.nxt
curr.nxt = node
else:
self.head = node
def print(self):
curr = self.head
while curr:
print(curr.val)
curr = curr.nxt
l1 = LinkedList()
l1.append(2) #Argument must be integer, not LinkedNode(integer)
l1.append(3) #Because you are already converting integer to LinkedNode on append function
l1.append(4)
l1.print()
Output:
2
3
4
Because in these lines you are creating LinkedNode objects not values!
l1.append(LinkedNode(2))
l1.append(LinkedNode(3))
l1.append(LinkedNode(4))
After that, you created a new LinkedNode(LinkedNode(2), None) within the scope of the append function.
Change it to:
l1.append(2)
l1.append(3)
l1.append(4)
class Node:
def __init__(self, data):
self.data = data
self.ref = None
class LinkedList:
def __init__(self):
self.head = None
def show(self):
if self.head is None:
print("This linked lists is empty")
else:
currentnode = self.head
while currentnode is not None:
print(currentnode.data, end=" --> ")
currentnode = currentnode.ref
def addelement(self, value):
newnode = Node(value)
newnode.ref = self.head
self.head = newnode
def lenofll(self , i = 0):
while self.head is not None:
i = i +1
self.head = self.head.ref
return i
def middle(self):
i = 0
lent = self.lenofll()
if self.head is None: # self.head changed to None after calling lenofll method.
print("linked list is empty")
I wanted to get the length of linked lists in the middle method. But as I called self.lenofll(), it changed the self.head to None.
What can I do to fix this?
Indeed, doing self.head = self.head.ref modifies the head. You should not make any modifications to self.head in a method whose job is just to search in the list -- without modifying anything to it.
As you can see, that method keeps looping until self.head is not None is not true, i.e. when self.head is None. No wonder that self.head is None after running this method!
Use a local variable for this iteration instead:
def lenofll(self, i = 0):
node = self.head # use local variable
while node is not None:
i += 1
node = node.ref
return i
I create a linked list using python class. But I can't manipulate the output format:
class Node:
def __init__(self, item=None):
self.item = item
self.next = None
class LinkedList:
def __init__(self):
self.head = Node()
def showElements(self):
curr = self.head
while curr is not None:
print(curr.item)
curr = curr.next
def append(self, item):
new_node = Node(item)
curr = self.head
while curr.next != None:
curr = curr.next
curr.next = new_node
llist = LinkedList()
llist.append(1)
print(llist.head.item) # output: None // But I want here to display 1
llist.append(2)
print(llist.head.next.item) # output: 1 // But I want here to display 2
llist.showElements() # output: None 1 2 // I want only 1 2
Maybe my first head node create this problem. But without initializing an empty node how could I create the reference of the next node using the next attribute?
You have to assign the head in the append function if there's no head already. The head was always an Empty Node
class Node:
def __init__(self, item=None):
self.item = item
self.next = None
class LinkedList:
def __init__(self):
self.head = None
def showElements(self):
curr = self.head
while curr is not None:
print(curr.item)
curr = curr.next
def append(self, item):
if self.head is None:
self.head = Node(item)
return
new_node = Node(item)
curr = self.head
while curr.next is not None:
curr = curr.next
curr.next = new_node
Your append method sets head.next to new_node, but it never sets head.item, which is why you get output=None.
So with this implementation, the head doesn't store an actual element, it's just used as a starting point for the list. That's not necessarily a problem, it's one implementation choice.
You could also change the implementation to store an item in head, why not.
Whatever the choice, I would suggest implementing first() and next() methods to hide the implementation details.
I'm new to python coming form c++ i don't know how to work with linked list without pointers, that being said I've written this code but it returns the same list without sorting it at all
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def insertionSortList(head):
if head.next==None:
return head
#checkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkks
loop=head
i=head
while(i.next!=None):
save_val=i.next
i=i.next.next
while True:
if loop!=i and save_val.val>loop.val:
loop=loop.next
else:
if loop==head:
save_val=loop
break
else:
save_val=loop.next
loop=save_val
loop=head
break
return head
You are not incrementing the loop node variable. Your code breaks out of the inner while loop before the loop node variable gets a chance to increment loop=loop.next. Here is my solution, I separated the Node and Linked List classes. Setup a length variable and incremented the value each time I inserted a node. Then used the normal insertion sort method.
class Node:
def __init__(self,value):
self.value = value
self.next = None
class ListNode:
def __init__(self):
self.head = None
self.length = 0
def __repr__(self):
'''Allows user to print values in the ListNode'''
values = []
current = self.head
while current:
values.append(current.value)
current = current.next
return ', '.join(str(value) for value in values)
def insert(self,value):
'''Inserts nodes into the ListNode class'''
newNode = Node(value)
if self.head is None:
self.head = newNode
else:
newNode.next = self.head
self.head = newNode
self.length += 1
return self
def insertionSortList(self):
'''Insertion sort method: held a temp variable and inserted the smallest value from temp through the rest of the list then incremented temp variable to the next idx/node'''
current = self.head
for _ in range(self.length-1):
tempNode = current.next
while tempNode:
if tempNode.value < current.value:
current.value, tempNode.value = tempNode.value, current.value
tempNode = tempNode.next
current = current.next
return self