Put node class into linked list class python - python

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

Related

Error: Merge two sorted linkedlist using dummy head technique in Python

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()

How can I add the second item in the linked list without overwriting the first one?

I've implemented a linked list in Python. The first item gets inserted properly. But the second one overwrites it in the head node. And after that it works just fine.
class Node:
def __init__(self):
self.data = None
self.next = None
class LinkedList:
def __init__(self):
self.head = Node()
self.iterator = self.head
def isEmpty(self):
if self.head.data is None:
return True
def insert(self, value):
if self.isEmpty():
self.head.data = value
else:
while self.iterator.next is not None:
self.iterator = self.iterator.next
self.iterator.next = Node()
self.iterator.data = value
self.iterator = self.head
def __str__(self):
l = []
while self.iterator.next is not None:
l.append(self.iterator.data)
self.iterator = self.iterator.next
self.iterator = self.head
return str(l)
t = LinkedList()
t.insert(2)
t.insert(4)
t.insert(8)
t.insert(6)
t.insert(10)
t.insert(12)
print(t)
Also in the str method how can I print the data if Head is the only node. (As Next of Head is None it will not enter the while loop.)
Here, you seem to overrwrite the data at self.iterator. Rather, you should set the data to the new node you created:
self.iterator.data = value
Fixed code:
class LinkedList:
def __init__(self):
self.head = Node()
self.iterator = self.head
def isEmpty(self):
if self.head.data is None:
return True
def insert(self, value):
if self.isEmpty():
self.head.data = value
else:
while self.iterator.next is not None:
self.iterator = self.iterator.next
new_node = Node()
new_node.data = value
self.iterator.next = new_node
self.iterator = self.head
Adding self.iterator.next = Node() inside the if statement of the method insert solved it for me:
class Node:
def __init__(self):
self.data = None
self.next = None
class LinkedList:
def __init__(self):
self.head = Node()
self.iterator = self.head
def isEmpty(self):
if self.head.data is None:
return True
def insert(self, value):
if self.isEmpty():
self.head.data = value
self.iterator.next = Node()
else:
while self.iterator.next is not None:
self.iterator = self.iterator.next
self.iterator.next = Node()
self.iterator.data = value
self.iterator = self.head
def __str__(self):
l = []
while self.iterator.next is not None:
l.append(self.iterator.data)
self.iterator = self.iterator.next
self.iterator = self.head
return str(l)
Output:
[2, 4, 8, 6, 10, 12]

Python doubly linked list

Please help me properly print my stackA class? Here is the current output. Also, how would I reverse the stackA?
C:\Users\Eli\PycharmProjects\GuessingGameReview\venv\Scripts\python.exe C:/Users/Eli/.PyCharmCE2019.2/config/scratches/Assignment_3.py
5
0
1
2
3
4
stackA is Empty!
[<__main__.Node object at 0x000001E54DEB0CC0>, <__main__.Node object at 0x000001E54DEB0C88>, <__main__.Node object at 0x000001E54DEB0C18>, <__main__.Node object at 0x000001E54DEB0BE0>, <__main__.Node object at 0x000001E54DEB0C50>]
[<__main__.Node object at 0x000001E54DEB0CC0>, <__main__.Node object at 0x000001E54DEB0C88>, <__main__.Node object at 0x000001E54DEB0C18>, <__main__.Node object at 0x000001E54DEB0BE0>, <__main__.Node object at 0x000001E54DEB0C50>]
[<__main__.Node object at 0x000001E54DEB0CC0>, <__main__.Node object at 0x000001E54DEB0C88>, <__main__.Node object at 0x000001E54DEB0C18>, <__main__.Node object at 0x000001E54DEB0BE0>, <__main__.Node object at 0x000001E54DEB0C50>]
Process finished with exit code 0
Process finished with exit code 0
class Node:
def __init__(self, data=None, next=None):
self.data = data
self.next = next
self.prev = None
class doublelyLinkedList:
def __init__(self,head = None, tail = None,size = 0):
self.head = head
self.tail = tail
self.size = size
def push(self, e):
self.__data.append(e)
def pop(self):
if self.empty():
# raise Empty(stack is empty)
print("stack is empty")
return
return self.__data.pop()
def empty(self):
return len(self.__data) == 0
def removeHead(self, head):
temp = head
obj = head.data
head = head.next
temp.next = None
return obj
def removetail(self):
temp = self.head
while temp.next:
R = temp
temp = temp.next
self.tail = temp.prev
R.next = None
return temp
def append(self,data):
if self.head is None:
new_node = Node(data)
new_node.prev = None
self.head = new_node
else:
new_node = Node(data)
cur = self.head
while cur.next:
cur = cur.next
cur.next = new_node
new_node.prev = cur
new_node.next = None
def prepend(self,data):
if self.head is None:
new_node = Node(data)
new_node.prev = None
self.head = new_node
else:
new_node = Node(data)
self.head.prev = new_node
new_node.next = self.head
self.head = new_node
def __repr__(self):
nodes = []
curr = self.head
while curr:
nodes.append(repr(curr))
curr = curr.next
return '[' + ', '.join(nodes) + ']'
def isempty(self):
return self.head == None and self.tail == None
def print_list(self):
cur = self.head
while cur:
print(cur.data)
cur = cur.next
class deque:
def __init__(self):
self.dlist = doublelyLinkedList
def front_pop(self,e):
self.dlist.prepend(e)
def front_push(self):
if self.dlist.isempty():
print("deque is empty")
return
return self.dlist.removeHead()
def back_pop(self,e):
self.dlist.prepend(e)
def back_push(self,e):
if self.dlist.isempty():
print("deque is empty")
return
return self.dlist.removetail()
def __repr__(self):
return doublelyLinkedList. __repr__(self.dlist)
class stackA:
def __init__(self):
self.dlist = doublelyLinkedList()
def push(self, e):
self.dlist.prepend(e)
def pop(self):
if self.dlist.isempty():
print("stackA is Empty!")
return
return self.dlist.removeHead
def reverse_stack(self):
rev = Queue
curr = self.dlist.tail
while curr:
rev.enqueue(curr)
curr = curr.prev
self.list = rev.dlist
def __repr__(self):
return doublelyLinkedList.__repr__(self.dlist)
class Queue:
def __init__(self):
self.dlist = doublelyLinkedList()
def enqueue(self, e):
self.dlist.append(e)
def dequeue(self):
if self.dlist.isempty():
print("Queue is Empty!")
return
return self.dlist.removeHead()
def __repr__(self):
return doublelyLinkedList.__repr__(self.dlist)
def ReverseStack(t):
e = Queue()
while t.dlist.head != None:
e.enqueue(stackA.pop(t))
print("!!!!")
if __name__ == "__main__":
dlist = doublelyLinkedList()
dlist.prepend(0)
dlist.append(1)
dlist.append(2)
dlist.append(3)
dlist.append(4)
dlist.prepend(5)
dlist.print_list()
deque = deque()
stackA = stackA()
Queue = Queue()
# stack TEST
stackA.pop()
stackA.push("Obama")
stackA.push("Donald")
stackA.push("Bush")
stackA.push("Lincoln")
stackA.push("Roosevelt")
print(stackA)
stackA.pop()
print(stackA)
stackA.reverse_stack()
print(stackA)
print()
Your Node class needs a __repr__ method if you want repr(curr) in your dlist's __repr__ to yield something useful:
def __repr__(self):
return repr(self.data)
The reverseStack method has at least one basic syntax error that you'll need to fix before you can make any progress on that part of the problem.

Python printing the value of the variable show <__main__.Element object at 0x10071d5d0>

Hi I am trying to print the value of "temp" variable so I use print(temp)
def delete_first(self):
if self.head:
deleted_element = self.head
temp = deleted_element.next
print(temp)
self.head = temp
return deleted_element
else:
return None
Why do I get an output like this? Is this that the object address in the memory? do I fix it so that it prints out more meaningful/readable object names?
<__main__.Element object at 0x10071d5d0>
Full code:
class Element(object):
def __init__(self, value):
self.value = value
self.next = None
class LinkedList(object):
def __init__(self, head=None):
self.head = head
def append(self, new_element):
current = self.head
if self.head:
while current.next:
current = current.next
current.next = new_element
else:
self.head = new_element
def insert_first(self, new_element):
new_element.next = self.head
self.head = new_element
def delete_first(self):
if self.head:
deleted_element = self.head
temp = deleted_element.next
print(temp)
self.head = temp
return deleted_element
else:
return None
class Stack(object):
def __init__(self, top=None):
self.ll = LinkedList(top)
def push(self, new_element):
self.ll.insert_first(new_element)
def pop(self):
return self.ll.delete_first()
# Test cases
# Set up some Elements
e1 = Element(1)
e2 = Element(2)
e3 = Element(3)
e4 = Element(4)
# Start setting up a Stack
stack = Stack(e1)
# Test stack functionality
stack.push(e2)
stack.push(e3)
print stack.pop().value
print stack.pop().value
print stack.pop().value
print stack.pop()
stack.push(e4)
print stack.pop().value
Full output:
<main.Element object at 0x10071d5d0>
3
<main.Element object at 0x10071d590>
2
None
1
None
None
4
You need to define a __str__ method for this class (if you own it, of course), like the toString() in Java.
For example:
class Element():
attr_1 = 0
attr_2 = 0
def __str__(self):
return '%s, %s' % (self.attr_1, self.attr_2)

Error displaying linked list data (missing last value)

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

Categories

Resources