So I have this code
class Node():
def __init__(self, data):
self.data = data
self.next = None
class LinkedList():
def __init__(self):
self.head = None
self.length = 0
def prepend(self, data):
new_node = Node(data)
new_node.next = self.head
self.head = new_node
self.length += 1
def print_list(self):
if self.head == None:
print('Empty')
else:
currentNode = self.head
while currentNode != None:
print(currentNode.data, end = ' ')
currentNode = currentNode.next
def reverse(self):
first = self.head
second = first.next
while second:
temp = second.next
second.next = first
first = second
second = temp
I prepend and then have a list of [8,7,11,6,5,10].
When I try to use the reverse function and try to print out I get infinite loop of 8 and 7. I'm not sure why. I thought the first already points to the self.head so that when it gets changed, the self.head gets changed as well. But its not the case. Could someone please help me with this?
Your reverse method is focussing on only the first two elements, and setting up cyclic references between them.
Here's the modified reverse() method, that works. (Note that the reverse() method contains an enclosed helper function called rev_(), which recurses through the linked list):
def reverse (self): #------------MODIFIED--------------
def rev_ (head):
rest = head.next
if rest is None:
return head
else:
reversed_rest = rev_(rest)
rest.next = head
head.next = None
return reversed_rest
if self.head is not None:
self.head = rev_(self.head)
Testing it out:
my_list = LinkedList()
my_list.print_list()
print()
my_list.reverse()
my_list.print_list()
print()
my_list.prepend(21)
my_list.print_list()
print()
my_list.reverse()
my_list.print_list()
print()
my_list.prepend(22)
my_list.prepend(23)
my_list.print_list()
print()
my_list.reverse()
my_list.print_list()
Output:
Empty
Empty
21
21
23 22 21
21 22 23
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)
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'm trying to implement a circular queue (without limited buffer) in python.
When I call display after enqueue, it doesn't work. However, it works fine when called in other cases.
Its implementation is similar to the get_size function which works as expected.
Below is the implementation:
class Node(object):
def __init__(self, value):
self.value = value
self.next = None
class LinkedCircularQueue(object):
def __init__(self, head=None, tail=None):
self.head = head
self.tail = tail
def enqueue(self, item):
"""
Add the node to the back of the queue and set its next pointer to
self.head
"""
if self.tail is not None:
self.tail.next = item
else:
self.head = item
self.tail = item
item.next = self.head
return self.tail.value
def dequeue(self):
"""
Remove the oldest node (from the front) by copying the value and
making the preceding node as the new head
"""
if self.head is not None:
deleted = self.head.value
self.head = self.head.next
else:
deleted = None
print("Circular queue is empty !!")
return deleted
def display(self):
"""
Traverse from front to back and show elements
"""
front = self.head
back = self.tail
if front is not None and back is not None:
while back.next != front:
print(front.value, end=" ")
front = front.next
else:
print("Circular queue is empty !!")
def get_size(self):
"""
Traverse from front to back and count elements
"""
size = 0
if self.head is not None and self.tail is not None:
while self.tail.next != self.head:
size += 1
self.head = self.head.next
return size
def peek_front(self):
front = self.head
return front.value
def peek_back(self):
back = self.tail
return back.value
def is_empty(self):
first = self.head
last = self.tail
if first is None and last is None:
return True
else:
return False
def main():
# Initialize elements
element1 = Node(1)
element2 = Node(2)
element3 = Node(3)
element4 = Node(4)
element5 = Node(5)
linked_circular_queue = LinkedCircularQueue()
# Initial tests
linked_circular_queue.display()
print(linked_circular_queue.is_empty())
print(linked_circular_queue.get_size())
print()
# Test enqueue
linked_circular_queue.enqueue(element5)
linked_circular_queue.enqueue(element3)
linked_circular_queue.enqueue(element1)
linked_circular_queue.enqueue(element4)
linked_circular_queue.enqueue(element2)
linked_circular_queue.display() # doesn't work
print()
# Test dequeue
linked_circular_queue.dequeue()
linked_circular_queue.dequeue()
linked_circular_queue.display()
print()
# Test peek
print(linked_circular_queue.peek_front())
print(linked_circular_queue.peek_back())
print()
# Final tests
print(linked_circular_queue.is_empty())
print(linked_circular_queue.get_size())
if __name__ == '__main__':
main()
Current Output:
Circular queue is empty !!
True
0
1 4 2
1
2
False
3
Expected Output:
Circular queue is empty !!
True
0
5 3 1 4 2
1 4 2
1
2
False
3
Change the while loop from the display function to this:
while back != front:
print(front.value, end=" ")
front = front.next
print(back.value) # print(front.value) also works
I am trying to write a program to merge two sorted linked lists.
But its not merging them.
it seems like the error is in representing head pointer.
how to represent head pointer? is my way correct.
I am facing a lot of problems using pointers pls give me some suggestions especially head pointer
merge two sorted linkedlist
class Node:
def __init__(self,data):
self.data=data
self.next =None
class linkedlist:
def __init__(self):
self.head=None
def push(self,ndata):
nnode = Node(ndata)
nnode.next = self.head
self.head = nnode
def addNodeToList(self,ndata):
nnode = Node(ndata)
if self.head is None:
self.head = nnode
return
last = self.head
while last.next is not None:
last = last.next
last.next = nnode
def printList(self):
temp = self.head
while temp is not None:
print(temp.data,end = ' ')
temp = temp.next
def merge(first,second):
dummy=linkedlist()
temp = dummy.head
temp1=first.head
temp2=second.head
while temp1 and temp2:
if temp1.data<temp2.data:
temp=temp1
temp.next=None
temp1=temp1.next
print('\n1..')
elif temp1.data>=temp2.data:
temp=temp2
temp.next=None
temp2=temp2.next
print('\n2..')
if temp1 is not None:
temp.next= temp1
print('\n3..')
else:
temp.next=temp2
print('\n4..')
print('Done')
return dummy
if __name__=='__main__':
list1=linkedlist()
list1.addNodeToList(10)
list1.addNodeToList(20)
list1.addNodeToList(30)
list1.addNodeToList(40)
list1.addNodeToList(50)
list2=linkedlist()
# Create linked list 2 : 5->15->18->35->60
list2.addNodeToList(5)
list2.addNodeToList(15)
list2.addNodeToList(18)
list2.addNodeToList(35)
list2.addNodeToList(60)
list1.printList()
print()
list2.printList()
a=merge(list1,list2)
a.printList()
Expected output is a single merged linkedlist
You already have the addNodeToList() function so why not use it?
def merge(first,second):
dummy=linkedlist()
temp1=first.head
temp2=second.head
while temp1 and temp2:
if temp1.data<temp2.data:
dummy.addNodeToList(temp1.data)
temp1=temp1.next
else:
dummy.addNodeToList(temp2.data)
temp2=temp2.next
while temp1:
dummy.addNodeToList(temp1.data)
temp1=temp1.next
while temp2:
dummy.addNodeToList(temp2.data)
temp2=temp2.next
return dummy
You are never adding to dummy in your code - you do temp = dummy.head and then you reassign temp and the dummy list is never updated. Here is an approach:
class Node:
def __init__(self, data):
self.data = data
self.next = None
class LinkedList: # classes in python must be in CamelCase
def __init__(self):
self.head = None
def push(self, ndata):
nnode = Node(ndata)
nnode.next = self.head
self.head = nnode
def addNodeToList(self, ndata):
nnode = Node(ndata)
if self.head is None:
self.head = nnode
return
last = self.head
while last.next is not None:
last = last.next
last.next = nnode
def printList(self):
temp = self.head
while temp is not None:
print(temp.data, end = ' ')
temp = temp.next
def walk_list(self):
temp = self.head
values = []
while temp is not None:
values.append(temp.data)
temp = temp.next
return values
def merge(first, second):
values1 = first.walk_list()
values1.extend(second.walk_list())
dummy = LinkedList()
for v in sorted(values1):
dummy.push(v)
return dummy
if __name__ == '__main__':
list1 = LinkedList()
list1.addNodeToList(10)
list1.addNodeToList(20)
list1.addNodeToList(30)
list1.addNodeToList(40)
list1.addNodeToList(50)
list2 = LinkedList()
# Create linked list 2 : 5->15->18->35->60
list2.addNodeToList(5)
list2.addNodeToList(15)
list2.addNodeToList(18)
list2.addNodeToList(35)
list2.addNodeToList(60)
list1.printList()
print()
list2.printList()
a = merge(list1, list2)
a.printList()
I am trying to write the list.append() operation in python. I implemented a linked list and it work fine. But I am not getting the last data item to be printed. When I try to print all the items in the list I get all the data value inside the node printed except the last one. I get 'None' printed instead of the value. I'm making some mistake in assigning the next pointer to 'None' in the newly added node. Need help in fixing.
Implementation of Node class and List class.
class Node:
def __init__(self,item):
self.data = item
self.next = None
def getData(self):
return self.data
def getNext(self):
return self.next
def setData(self,newItem):
self.data = newItem
def setNext(self, newNext):
self.next = newNext
class UnorderedList:
def __init__(self):
self.head = None
def isEmpty(self):
return self.head == None
def add(self,item):
temp = Node(item)
temp.setNext(self.head)
self.head = temp
def size(self):
count = 0
current = self.head
while current != None:
count = count + 1
current = current.getNext()
def append(self, item):
current = self.head
isEnd = False
newItem = Node(item)
while not isEnd:
if current.getNext() == None:
isEnd = True
else:
current = current.getNext()
current = current.setNext(newItem)
newItem = current.getNext()
def printList(self):
current = self.head
isEnd = False
while not isEnd:
if current.getNext() == None:
isEnd = True
else:
print current.getData()
current = current.getNext()
I create an object and pass values.
mylist = UnorderedList()
mylist.add(31)
mylist.add(77)
mylist.add(17)
mylist.add(93)
mylist.add(26)
mylist.add(54)
print(mylist.size())
mylist.append(12)
print(mylist.size())
mylist.append(15)
print(mylist.size())
print('\n')
print mylist.printList()
Output is:
6
7
8
54
26
93
17
77
31
12
None
The problem is you are doing
print(mylist.printList())
while printList() doesn't actually return anything. That's the last None printed there.
Hope this helps:
current = self.head
while(current!=None):
print(current.getData())
current=current.getNext()
This should be placed inside printlist.
And called this way :
mylist.printlist()
54
26
93
17
77
31
12
15
Edit :
I had also modified your append function to :
def append(self, item):
print("append",item)
current = self.head
isEnd = False
newItem = Node(item)
while not isEnd:
if current.getNext() == None:
isEnd = True
else:
current = current.getNext()
print("\Appending to",current.getData())
current.setNext(newItem)
current=current.getNext()
print("\tAppended",current.getData())