Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.
I have it almost complete. I cant get it to work. Any hints to make it work will be appreciated.
class node():
def __init__(self, data, next_node):
self.data = data
self.next_node = None
def get_data(self):
return self.data
def get_next(self):
return self.next_node
def set_next(self, new_node):
self.next_node = new_node
class LinkList(object):
def __init__(self, head = None):
self.head = head
def add(self, data):
new_node = node(data)
new_node.set_next(self.head)
self.head = new_node
def printlist(self):
current_node = self.head
while (current_node != None):
print(current_node.get_data(), end="->")
current_node = current_node.get_next()
def merge(L1, L2):
temp = None
if L1 is None:
return L2
if L2 is None:
return L1
if L1.data <= L2.data:
temp = L1
temp.next_node = merge(L1.next_node, L2)
else:
temp = L2
temp.next_node = merge(L1,L2.next_node)
return temp
def main():
list1 = LinkList()
list1.add(10)
list1.add(20)
list1.add(30)
list2 = LinkList()
list2.add(10)
list2.add(30)
list2.add(50)
list3 = LinkList()
list3.head = merge(list1.head, list2.head)
print("merge link list: ", end=" " )
list3.printlist()
if __name__ == "__main__":
main()
Since you are adding to the head of the list:
def add(self, data):
new_node = node(data)
new_node.set_next(self.head)
self.head = new_node
That means your list is reversed. Therefore you have to do a reverse check during the merge:
if L1.data >= L2.data:
full text:
class node():
def __init__(self, data, next_node = None):
self.data = data
self.next_node = next_node
def get_data(self):
return self.data
def get_next(self):
return self.next_node
def set_next(self, new_node):
self.next_node = new_node
class LinkList(object):
def __init__(self, head = None):
self.head = head
def add(self, data):
new_node = node(data)
new_node.set_next(self.head)
self.head = new_node
def printlist(self):
current_node = self.head
while (current_node != None):
print (current_node.get_data(), end = "->")
current_node = current_node.get_next()
print ()
def merge(L1, L2):
temp = None
if L1 is None:
return L2
if L2 is None:
return L1
if L1.data >= L2.data:
temp = L1
temp.next_node = merge(L1.next_node, L2)
else:
temp = L2
temp.next_node = merge(L1, L2.next_node)
return temp
def main():
list1 = LinkList()
list1.add(10)
list1.add(20)
list1.add(30)
print("list2: ", end=" " )
list1.printlist()
list2 = LinkList()
list2.add(11)
list2.add(21)
list2.add(51)
print("list2: ", end=" " )
list2.printlist()
list3 = LinkList()
list3.head = merge(list1.head, list2.head)
print("merge link list: ", end=" " )
list3.printlist()
if __name__ == "__main__":
main()
you only pass data argument,so set the next_node default value None
class node:
def __init__(self, data, next_node=None):
self.data = data
self.next_node = None
below is the ascending sorted solution
class Node(object):
def __init__(self, data):
self.data = data
self.next = None
def __str__(self):
return "<Node>{}</Node> {}".format(self.data, self.next)
class LinkList(object):
def __init__(self):
self.current = self.head = None
def add(self, node):
if not self.head:
self.head = self.current = node
else:
self.current.next = node
self.current = node
def __str__(self):
return "<head>{}</head> {}".format(self.head.data, self.head.next)
def merge(lst1, lst2):
rtn = LinkList()
while lst1 and lst2:
if lst1.data < lst2.data:
rtn.add(Node(lst1.data))
lst1 = lst1.next
else:
rtn.add(Node(lst2.data))
lst2 = lst2.next
if lst1:
rtn.add(lst1)
if lst2:
rtn.add(lst2)
return rtn
def main():
lst = LinkList()
lst.add(Node(1))
lst.add(Node(2))
lst.add(Node(3))
lst2 = LinkList()
lst2.add(Node(1.1))
lst2.add(Node(2.1))
lst2.add(Node(3.1))
rtn = merge(lst.head, lst2.head)
print(rtn)
if __name__ == '__main__':
main()
Related
I tried to remove the banana from the method remove_by_value, but it was unable to remove.
class LinkedList:
def __init__(self):
self.head = None
def insert_at_end(self, data):
if self.head is None:
self.head = Node(data, None)
return
itr = self.head
while itr.next:
itr = itr.next
itr.next = Node(data, None)
def insert_values(self, data_list):
self.head = None
for data in data_list:
self.insert_at_end(data)
def remove_by_value(self,data):
itr = self.head
if itr is None:
return
if itr.data == data:
itr.next = itr.next
return
while itr:
if itr.next.data == data:
itr.next = itr.next.next
break
itr = itr.next
if __name__ == '__main__':
ll = LinkedList()
ll.insert_values(["banana","mango","grapes","orange"])
ll.print() # from method to show all object.
ll.remove_by_value2("banana")
ll.print()
output:
banana=>mango=>grapes=>orange=>
banana=>mango=>grapes=>orange=>
please look here at the part of the remove node:
https://www.tutorialspoint.com/python_data_structure/python_linked_lists.htm
this is how you suppose to implement a linked list in python :)
let me know if you have more questions about it
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
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]
I'm trying to create 2 single linked lists and find the intersection between them. I'm getting errors such as NameError: obj is not defined for the LinkedList line and would like a working solution. How do I make this work? What am I doing wrong? Am I even close? What is the meaning of life? This is in python.
class IntersectSolution:
def intersect(sll_a, sll_b):
b_x_node = sll_b
while sll_b and not sll_a.search(sll_b.get_data()):
sll_b.get_next()
b_x_node = sll_b
if b_x_node == None:
print("No intersections between nodes.")
print("Intersection node is: {}".format(b_x_node))
class Node:
def __init__(self, data = None, next_node = None):
self.data = data
self.next_node = next_node
def get_data(self):
return self.data
def get_next(self):
return self.next_node
def set_next(self, new_node):
self.next_node = new_node
class LinkedList(obj):
def __init__(self, head = None):
self.head = head
def insert(self, data):
new_node = Node(data)
new_node.set_next(self.head)
self.head = new_node
def size(self):
current = self.head
count = 0
while current:
count += 1
current = current.get_next
return count
def search(self, data):
current = self.head
found = False
while current and found is False:
if current.get_data() == data:
found = True
else:
current = current.get_next()
if current is None:
raise ValueError("Data not in list")
return current
def delete(self, data):
current = self.head
previous = None
found = False
while current and found is False:
if current.get_data() == data:
found = True
else:
previous = current
current = current.get_next()
if current is None:
raise ValueError("Data not in list")
if previous is None:
self.head = current.get_next()
else:
previous.set_next(current.get_next())
a = LinkedList(Node)
b = LinkedList(Node)
for i in range(1, 15, 2):
a.insert(i)
for j in range(23, 8, -3):
b.insert(j)
ISoln = IntersectSolution
ISoln.intersect(a,b)
You can concatenate both linked-lists by implementing a custom __add__ method and then finding the values in the concatenated result that exist in both original lists:
class LinkedList:
def __init__(self, _val=None):
self.val = _val
self._next = None
def insert(self, _val):
if self.val is None:
self.val = _val
else:
getattr(self._next, 'insert', lambda x:setattr(self, '_next', LinkedList(x)))(_val)
def __iter__(self): #iterate over all values in list
yield self.val
yield from [[], self._next][bool(self._next)]
def __add__(self, _list): #concatenate two linkedlists
_l = self.__class__()
for i in _list:
_l.insert(i)
for i in self:
_l.insert(i)
return _l
def __contains__(self, _val): #check if a value exists in the list
if self.val is None:
return False
return True if self.val == _val else getattr(self._next, '__contains__', lambda _:False)(_val)
#classmethod
def intersection(cls, _a, _b):
_result = cls()
for i in (_a+_b):
if i in _a and i in _b and i not in _result:
_result.insert(i)
return _result
l = LinkedList()
for i in range(10):
l.insert(i)
l1 = LinkedList()
for i in range(6, 14):
l1.insert(i)
_intersection = LinkedList.intersection(l, l1)
print([i for i in _intersection])
Output:
[6, 7, 8, 9]
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)