I am working on implementing linked list to study data structure.There are many good resources on the Internet, but I still don't understand what part of my code does not work.
class Node:
def __init__(self, val=None):
self.data = val
self.Next = None
class LinkedList:
def __init__(self):
self.head = None
self.size = 0
def __repr__(self):
temp = self.head
alist = []
while temp.Next is not None:
alist.append(temp.data)
temp = temp.Next
return str(alist)
def add(self, val):
cur = self.head
prev = None
if cur is None:
self.head = Node(val)
else:
while cur is not None:
prev = cur
cur = cur.Next
prev.Next = Node(val)
self.size += 1
if __name__ == '__main__':
alist = LinkedList()
for i in range(10):
alist.add(i)
print(alist)
""" [0,1,2,3,4,5,6,7,8]
I expected it prints out [0,1,2,3,4,5,6,7,8,9] but it misses last element. Can anybody tell me what I missed on my add method please?
Thanks in advance!
To be clear, my original add method was like this,
def add(self, val):
temp = Node(val)
temp.Next = self.head
self.head = temp
self.size += 1
However, it adds elements reverse order, like [9,8,7,6,5,4,3,2,1,0]. So I changed my add to
def add(self, val):
cur = self.head
prev = None
if cur is None:
self.head = Node(val)
else:
while cur is not None:
prev = cur
cur = cur.Next
prev.Next = Node(val)
self.size += 1
I did not have problem to print out all elements inside of linked list previously, however new way does not print out last element. It was my __repr__ problem not add. I changed my __repr__. Thank you #inspectorG4dget
Related
I'm trying to solve merge two sorted linkedlist problem using dummy head technique. For some reason I have an error coming from passing an argument to my dummy head holder. The output suppose to merge both linkedlist like this: 1-> 1-> 2-> 3-> 7-> None
I would be happy if you please guide which data needs to pass in my dummy head variable? Thanks in advance! This is the error I have:
dummy = LinkedList()
TypeError: __init__() missing 1 required positional argument: 'data
Here's my complete code:
class LinkedList:
def __init__(self, data):
self.data = data
self.next = None
def print_list(head: LinkedList) -> None:
while head:
print(head.data, end=" -> ")
head = head.next
print("None")
def merge_lists(headA, headB):
dummy = LinkedList()
curr = dummy
while headA != None and headB != None:
if headA.data < headB.data:
curr.next = headA
headA = headA.next
else:
curr.next = headB
headB = headB.next
curr = curr.next
if headA != None:
curr.next = headA
else:
curr.next = headB
return dummy.next
node1 = LinkedList(1)
node1.next = LinkedList(2)
node1.next.next = LinkedList(7)
node2 = LinkedList(1)
node2.next = LinkedList(3)
print(merge_lists(node1, node2)) # 1-> 1-> 2-> 3-> 7-> None
Since it is a dummy node, and you never ever use the data attribute of that node, you can pass anything as argument, like None:
dummy = LinkedList(None)
Alternatively, you could specify that providing an argument is optional, and define the constructor as follows:
class LinkedList:
def __init__(self, data=None):
self.data = data
self.next = None
Unrelated, but at the end of your script you have:
print(merge_lists(node1, node2))
This will print the object reference. You probably wanted to call the function you have defined for this purpose:
print_list(merge_lists(node1, node2))
If you want print to work like that, then instead of the print_list function, enrich LinkedList with an __iter__ method to ease iteration over the values in the list, and a __repr__ or __str__ method as follows:
class LinkedList:
def __init__(self, data=None):
self.data = data
self.next = None
def __iter__(self):
head = self
while head:
yield head.data
head = head.next
yield None # Optional
def __repr__(self):
return " -> ".join(map(str, self))
...and then you can do
print(merge_lists(node1, node2))
class node:
def __init__(self, data):
self.data = data
self.next = None
class linkedList:
def __init__(self):
self.head = None
def insertNode(self, data):
newnode = node(data)
if self.head is None:
self.head = newnode
else:
current = self.head
while current.next is not None:
current = current.next
current.next = newnode
def printLL(self):
current = self.head
while current.next is not None:
print(current.data, end='----->')
current = current.next
print(current.data, '------>None')
def sortLL(self):
arr=[]
current = self.head
while current.next is not None:
arr.append(current.data)
current = current.next
arr.append(current.data)
arr.sort()
self.head = None
for i in arr:
self.insertNode(i)
def mergeTwoSortedLL(l, l2):
current1 = l.head
current2 = l2.head
l3 = linkedList()
while current1 is not None and current2 is not None:
if current1.data < current2.data:
l3.insertNode(current1.data)
current1 = current1.next
else:
l3.insertNode(current2.data)
current2 = current2.next
if current1 is None:
while current2.next is not None:
l3.insertNode(current2.data)
current2 = current2.next
l3.insertNode(current2.data)
else:
while current1.next is not None:
l3.insertNode(current1.data)
current1 = current1.next
l3.insertNode(current1.data)
return l3
l = linkedList()
l.insertNode(9)
l.insertNode(18)
l.insertNode(11)
l.insertNode(15)
l.insertNode(1)
l.insertNode(8)
l.sortLL()
l.printLL()
l2 = linkedList()
l2.insertNode(9)
l2.insertNode(18)
l2.insertNode(11)
l2.insertNode(15)
l2.insertNode(1)
l2.insertNode(8)
l2.sortLL()
l2.printLL()
mergeTwoSortedLL(l,l2).printLL()
This is my node class and Mylist class
class Node:
def __init__(self, data=None, next=None):
self.data = data
self.next = next
class MyList():
def __init__(self,head=None):
self.head = head
def showList(self):
temp = self.head
while (temp):
print(temp.data)
temp = temp.next
if self.head is None:
print("Empty List")
This is my showeven number function
def showeven(even):
head = None
while even:
if even.data % 2 == 0:
new_Node = Node(even.data, None)
if head is None:
tail = new_Node
head = new_Node
else:
tail.next = new_Node
tail = new_Node
MyList(head).showList()
Can you guys help me create a tester class or some sort of thing for this
You can simply write something like this.
def print_even_nodes(self):
traverse = self.head
while (traverse != None):
if (traverse.data % 2 == 0):
print(traverse.data)
traverse = traverse.next
It is pretty much similar to printing the whole singly linked list, the only key difference is that we check if that particular node (node.data field) is divisible by 2. If it is true we print out the element else we go to the next node.
This is my first time learning python
, just trying to create a simple linked list
here is the code
class node:
def __init__(self, data = None):
self.data = data
self.next = None
class linked_list:
def __init__(self):
self.head = node()
def append(self, data):
new_node = node(data)
cur = self.head
while cur.next != None:
cur = cur.next
cur.next = new_node
def length(self):
cur = self.head
total = 0
while cur.next != None:
total += 1
cur = cur.next
return total
#property
def display(self):
elems = []
cur_node = self.head
while cur_node.next != None:
cur_node = cur_node.next
elems.append(cur_node.data)
print(elems)
def get(self, index):
if index >= self.length():
print('index out of range')
return None
cur_idx = 0
cur_node= self.head
while True:
cur_node = cur_node.next
if cur_idx == index: return cur_node.data
cur_idx+= 1
def erase(self, index):
if index >= self.length():
print('index out of range')
return None
cur_idx = 0
cur_node = self.head
while True:
last_node = cur_node
cur_node = cur_node.next
if cur_idx == index:
last_node.next = cur_node.next
return
cur_idx+= 1
l1 = linked_list()
l1.append(8)
l1.append(7)
l1.append(6)
l1.append(5)
print(l1.get(0))
print(l1.get(1))
print(l1.get(2))
print(l1.get(3))
everything went well except when I tried to put node class into linked list class as an inner class like below:
class linked_list:
class node:
def __init__(self, data = None):
self.data = data
self.next = None
def __init__(self):
self.head = node()
def append(self, data):
new_node = node(data)
cur = self.head
while cur.next != None:
cur = cur.next
cur.next = new_node
......
(the rest are the same as the code above)
I got this error :
Traceback (most recent call last):
File "c:\blahblah\Basic_exercise.py", line 65, in <module>
l1 = linked_list()
File "c:\blahblah\Basic_exercise.py", line 11, in __init__
self.head = node()
NameError: name 'node' is not defined
1.what logic did I miss here?
2.Is there any way that I can treat node class as an inner class without getting errors?
The error you are seeing is due to the way you are referencing your innner class - it is a namespace issue. To disambiguate your inner node class from other node classes, you need to reference it by first using the outer class: linked_list.node.
Example:
class linked_list:
class node:
def __init__(self, data = None):
self.data = data
self.next = None
def __init__(self):
self.head = linked_list.node()
def append(self, data):
new_node = linked_list.node(data)
cur = self.head
while cur.next != None:
cur = cur.next
cur.next = new_node
If you want to keep the node class inside the linked_list class then you need to call the node class from the linked list class. So to do that you must do new_node = linked_list.node(data) . Rest all should be the same
In my last code for removing duplicates, the method removeDup isn't working.
The last print(ll.display()) is printing the previous linked list.
I was hoping it to print only unique nodes. What am I missing in removeDups method?
I can't figure out. What is happening in the code here?
class Node:
def __init__(self,data = None):
self.data = data
self.next = None
def __repr__(self):
return self.data
class LList:
def __init__(self):
self.head = None
def display(self):
current = self.head
node = []
while current != None:
node.append(current.data)
current = current.next
return node
def append(self, data):
elem = Node(data)
if self.head == None:
self.head = elem
else:
current = self.head
while current.next != None:
current = current.next
current.next = elem
def add_atFront(self, data):
elem = Node(data)
if self.head == None:
self.head = elem
else:
elem.next = self.head
self.head = elem
def removeDup(self):
current = self.head
previous = None
elems = []
while current != None:
if current.data in elems:
previous.next= current.next
else:
elems.append(current.data)
previous = current
current = current.next
ll= LList()
print(ll.display())
ll.append(65)
ll.append(7)
ll.add_atFront('65')
ll.add_atFront('Bare')
ll.insert('10',0)
ll.insert('7',2)
print(ll.display())
ll.removeDup()
print(ll.display())
Your removeDup works fine, the issue is that 65 and '65' are not duplicates, so you should not expect removeDup to dedup them. The same goes for 7 and '7'. Also, note you never defined the insert method, but I'll assume that's just a copy error.
I've implemented a Linked List class and I have a selectionSort and insertionSort function created that works on regular lists. I need to get selectionSort and insertionSort to work on linked lists, but I'm not sure where to even start, if I'm being honest.
Here's my linked list class:
class Node:
def __init__(self, initdata):
self.data = initdata
self.next = None
def getData(self):
return self.data
def getNext(self):
return self.next
def setData(self,newdata):
self.data = newdata
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 length(self):
current = self.head
count = 0
while current != None:
count = count + 1
current = current.getNext()
return count
def search(self, item):
current = self.head
found = False
while current != None and not found:
if current.getData() == item:
found = True
else:
current = current.getNext()
return found
def remove(self, item):
current = self.head
previous = None
found = False
while not found:
if current.getData() == item:
found = True
else:
previous = current
current = current.getNext()
if previous == None:
self.head = current.getNext()
else:
previous.setNext(current.getNext()
Here's my code for selectionSort and insertionSort. They work just fine on regular lists, but I'm having a lot of trouble figuring out where to start to get them to work on a linkedlist (unordered list).
def selectionSort(alist):
for fillslot in range(len(alist)-1,0,-1):
positionOfMax = 0
for location in range(1,fillslot+1):
if alist[location]>alist[positionOfMax]:
positionOfMax = location
temp = alist[fillslot]
alist[fillslot] = alist[positionOfMax]
alist[positionOfMax] = temp
def insertionSort(alist):
for index in range(1,len(alist)):
currentvalue = alist[index]
position = index
while position>0 and alist[position-1]>currentvalue:
alist[position] = alist[position-1]
position = position-1
alist[position] = currentvalue
Any suggestions/hints would be greatly appreciated.
I tried to implement insertionSort, The code is readable. SelectionSort should be similar, try to implement it.
def insertionSort(h):
if h == None:
return None
#Make the first node the start of the sorted list.
sortedList= h
h=h.next
sortedList.next= None
while h != None:
curr= h
h=h.next
if curr.data<sortedList.data:
#Advance the nodes
curr.next= sortedList
sortedList= curr
else:
#Search list for correct position of current.
search= sortedList
while search.next!= None and curr.data > search.next.data:
search= search.next
#current goes after search.
curr.next= search.next
search.next= curr
return sortedList
def printList(d):
s=''
while d:
s+=str(d.data)+"->"
d=d.next
print s[:-2]
l= unorderedList()
l.add(10)
l.add(12)
l.add(1)
l.add(4)
h= l.head
printList(h)
result= insertionSort(l.head)
d= result
printList(d)
Output:
4->1->12->10
1->4->10->12