adding link in link list- python - python

I tried to add link to link list but program is taking Nodes as an integer and not Node plz help me out in it
class Node(object):
def __init__(self, data):
self.data = data
self.next = None
class LinkedList(object):
def __init__(self):
self.head = None
def push(self, new_data):
new_node = Node(new_data)
new_node.next = self.head
self.head = new_node
def add_link(self, new_link, after_link):
new_link = Node(new_link)
new_link.next = after_link.next
after_link.next = new_link
def printList(self):
temp = self.head
while(temp):
print temp.data,
temp = temp.next
llist = LinkedList()
llist.push(20)
llist.push(4)
llist.push(15)
llist.push(85)
print "Given Linked List"
llist.printList()
llist.add_link(35, 4)
print "\nAfter adding Link new Linked List"
llist.printList()
The Error is on new_link.next = after_link.next
AttributeError: 'int' object has no attribute 'next'

You have to just make a slight change in the add link function.
def add_link(self, new_link, after_link):
new_link = Node(new_link)
after_link=Node(after_link)
new_link.next = after_link.next
after_link.next = new_link
This is because you are passing an integer(after_link) to the function and then using after_link.next which is not possible because after_link is an integer .So first you have to make a Node with its data as the after_link integer

You have to create the object of type Node in which you will pass data and next
sample code
node_obj = Node(34,4)
moreover in function add_link(self, new_link, after_link),both parameters of new_link and after_link are of type Node

Related

Linked List, can't acess the data from NEXT NODE

My problem is at the display function, I can't access the value cur_node.data which is a reference to node.next.data. I'm new to python and I'm trying to learn Linked LISTS, this code is from an old VIDEO which is why it probably isn't working
My code below:
class node:
def __init__(self,data=None):
self.data =data
self.next = None
class linkedlist:
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 lenght(self):
count = 0
start = self.head
while start.next!=None:
count+=1
start = start.next
return count
def display(self):
elements = []
cur_node = self.head
while cur_node !=None:
cur_node = cur_node.next
elements.append(cur_node.data) # here at cur_node.data its not accessing DATA from the NODE
print(elements)
if __name__ =='__main__':
pass
li = linkedlist()
li.append(5)
li.append(5)
li.display()
it's expected to display the array made of the nodes at the display() function
Fala Brazuca,
The problem is with your while condition.
while cur_node != None
cur_node = cur_node.next
See carefully,
When your loop is iterating on the last element, cur_node still have data on it, but its next element does not.
What your code is saying is -> If the last element has data, then assume a None type, which doesn't have an attribute called data. Therefore, causing the AttributeError.
elements.append(cur_node.data)
AttributeError: 'NoneType' object has no attribute 'data'
This is easily solved by especifying that the NEXT element can't be None.
Final result:
def display(self):
elements = []
cur_node = self.head
while cur_node.next != None:
cur_node = cur_node.next
elements.append(cur_node.data)
print(elements)

why the element not appending in linked list?

not getting expected output. Missing node with data = 6
looks like not insertAfter method properly,
cant find the issue.
pls suggest any other issue too as i am just started with data structures. is there anything need to be kept in mind while studying data structures.
class Node:
def __init__(self,data):
self.data = data
self.next = None
class LinkeList:
def __init__(self):
self.head = None
def push(self,new_data):
new_node = Node(new_data)
new_node.next = self.head
self.head = new_node
def insertAfter(self,prev_node,new_data):
new_node = Node(new_data)
if self.head is None:
self.head = new_node
return
new_node.next = prev_node.next
prev_node.next = new_node
def append(self,new_data):
new_node = Node(new_data)
if self.head is None:
self.head = new_node
return
last = self.head
while last.next != None:
last = last.next
last.next = new_node
def printList(self):
temp = self.head
while temp is not None:
print(temp.data, end = " ")
temp = temp.next
if __name__ =='__main__':
llist = LinkedList()
llist.append(7)
llist.append(8)
llist.push(5)
llist.insertAfter(Node(5),6)
llist.printList()
So the issue is in this line,
llist.insertAfter(Node(5),6)
When you do insertAfter then you need to first get a Node from the current linked list, rather what you are doing is, that you create a new node, then pass it. That new node might have the same value as a . node in your linked list, but it really isn't a part of it, what you need to do is as follows
First implement a get node function, that gets a node from the linked list with the value that you want, something like this
def getNode(self, value):
temp = self.head
while temp is not None:
if temp.value == value:
return temp
else:
temp = temp.next
return None
then do this.
llist.insertAfter(llist.getNode(5),6)
Also put a check for if passed node is not None in insertAfter

Why this code is running without errors ? Reverse a link list

Given a linked list, write a function to reverse every k nodes (where k is an input to the function).
Examples:
Inputs: 1->2->3->4->5->6->7->8->NULL and k = 3
Output: 3->2->1->6->5->4->8->7->NULL.
Inputs: 1->2->3->4->5->6->7->8->NULL and k = 5
Output: 5->4->3->2->1->8->7->6->NULL.
This is the Code:
# Node class
class Node:
# Constructor to initialize the node object
def __init__(self, data):
self.data = data
self.next = None
class LinkedList:
# Function to initialize head
def __init__(self):
self.head = None
def reverse(self, head, k):
current = head
Next = None
prev = None
count = 0
# Reverse first k nodes of the linked list
while(current is not None and count < k):
Next = current.next
current.next = prev
prev = current
current = Next
count += 1
# next is now a pointer to (k+1)th node
# recursively call for the list starting
# from current . And make rest of the list as
# next of first node
if Next is not None:
head.next = self.reverse(Next, k)
# prev is new head of the input list
return prev
# Function to insert a new node at the beginning
def push(self, new_data):
new_node = Node(new_data)
new_node.next = self.head
self.head = new_node
# Utility function to print the linked LinkedList
def printList(self):
temp = self.head
while(temp):
print temp.data,
temp = temp.next
# Driver program
llist = LinkedList()
llist.push(9)
llist.push(8)
llist.push(7)
llist.push(6)
llist.push(5)
llist.push(4)
llist.push(3)
llist.push(2)
llist.push(1)
print "Given linked list"
llist.printList()
llist.head = llist.reverse(llist.head, 3)
print "\nReversed Linked list"
llist.printList()
On my computer, this code gives me error saying "LinkedList class has no attribute next" => the error in this statement "Next = current.next" . On Geeks for Geeks the code is running fine. Also on all the online IDEs the code is running fine. So is it something wrong with my device or the code should not run ?

Insertion before a node in Doubly link list

i'm trying to insert a node before a node into doubly linked list.After performing the operation i'm not getting the correct results.
class createnode:
def __init__(self,data):
self.data=data
self.next=None
self.prev=None
class Unordered_list:
def __init__(self):
self.head=None
######Insertion at the starting###
def buildlst(self,data):
node=createnode(data)
if self.head is None:
self.head=node
else:
node.next=self.head
node.prev=None
self.head=node
#######INsertion at the end####
def buildlstend(self,data):
node=createnode(data)
ptr=self.head
while(ptr.next):
ptr=ptr.next
ptr.next=node
ptr=node.prev
#######INsertion before some node i.e searched node####
def insertbeforenode(self,data,srch_data):
node=createnode(data)
ptr=self.head
while(ptr):
if ptr.data==srch_data:
node.prev=ptr.prev
node.next=ptr
ptr.prev=node
ptr=ptr.next
########Printitng the list########
def printlist(self):
temp=self.head
while(temp):
print(temp.data)
temp=temp.next
A=Unordered_list()
A.buildlst(10)
A.buildlst(20)
A.buildlstend(30)
A.printlist()
print("Here i will insert a new node 50 before 10")
A.insertbeforenode(50,10)
A.printlist()
Mylist look some what like 20,10,30.I want to have the new node before 10.but it prints me the same results.Have been through this link Inserting a node before a given node in doubly linked list .My program is in python so couldn.t collect much from it.
insertbeforenode is my function from where i'm making a call.
Python supports a built-in mechanism to work with lists, you could easily do something like this:
list = []
list.append(10)
list.insert(0, 20)
list.append(30)
list.insert(1, 50)
See the official documentation for more examples https://docs.python.org/3/tutorial/datastructures.html.
Anyway if you want to program a double linked list by your self I have made some changes to your code:
class createnode:
def __init__(self, data):
self.data = data
self.next = None
self.prev = None
class Unordered_list:
def __init__(self):
self.head = None
def buildlst(self, data):
node = createnode(data)
if self.head is None:
self.head = node
else:
node.next = self.head
self.head.prev = node # <---
# node.prev = None <---- this is not necessary
self.head = node
def buildlstend(self, data):
node = createnode(data)
ptr = self.head
while ptr.next:
ptr = ptr.next
ptr.next = node
node.prev = ptr # <---
def insertbeforenode(self, data, srch_data):
if srch_data == self.head.data: # <-- if you try to insert before the head
self.buildlst(data)
else:
node = createnode(data)
ptr = self.head
while ptr:
if ptr.data == srch_data:
node.prev = ptr.prev
node.next = ptr
ptr.prev = node
node.prev.next = node # <--
break # <--- when you find your node you have to quit from the loop
else:
ptr = ptr.next
def printlist(self):
temp = self.head
while (temp):
print(temp.data)
temp = temp.next
I have put an arrow (# <--) where I made the changes. There were a couples of mistakes on working with pointers and others inaccuracies. Please try this and let me know!

python class object and variables lifetime

class Node:
def __init__(self):
self.data = None # contains the data
self.next = None # contains the reference to the next node
class linked_list:
def __init__(self):
self.cur_node = None
self.counter = 0
def add_node(self, data):
new_node = Node() # create a new node
new_node.data = data
new_node.next = self.cur_node # link the new node to the' previous' node.
self.cur_node = new_node # set the current node to the new one.
def list_print(self):
node = self.cur_node # cant point to ll!
while node:
print node.data
node = node.next
ll = linked_list()
ll.add_node(1)
ll.add_node(2)
ll.add_node(3)
ll.list_print()
I am creating the object of linked_list class.
After that i am calling the member function add_node() three times.
but when i call the function list_print it prints 3->2->1.
my question is here is that how is it printing it? according to me it should print "3" only because when i call ll.list_print() the value of self.cur_node is equal to 3. so how is it printing the all three inputs. where is it storing the previous values "2,1" ? please help me out.
At the add_note method you are declaring new_node.next = to self.cur_node before declaring this last first, but, this is unnecessary. Comment that line! I've added a print to check the progress within that method
class Node:
def __init__(self):
self.data = None # contains the data
self.next = None # contains the reference to the next node
class linked_list:
def __init__(self):
self.cur_node = None
self.counter = 0
def add_node(self, data):
new_node = Node() # create a new node
new_node.data = data
#new_node.next = self.cur_node # link the new node to the' previous' node.
print(self.cur_node)
self.cur_node = new_node # set the current node to the new one.
def list_print(self):
node = self.cur_node # cant point to ll!
while node:
print node.data
node = node.next
ll = linked_list()
ll.add_node(1)
ll.add_node(2)
ll.add_node(3)
ll.list_print()

Categories