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()
Related
I want to make a linked list by dummy headed circular but I can't understand why the code is printing reverse.
class Node:
def __init__(self, value, next, prev ):
self.data = value
self.next = next
self.prev = prev
class DoublyList:
def __init__(self, c):
self.head = Node(None,None,None) #instance variable
self.head.prev = self.head.next = self.head
for i in c:
store = Node(i, None, None)
store.next = self.head.next
store.prev = self.head
self.head.next = store
store.next.prev = store
def showList(self):
n = self.head.next
while n !=self.head:
print(n.data, end=' ')
n = n.next
a = [10,20,30,40,50,60]
l1 = DoublyList(a)
l1.showList()
Since you want to add each subsequent node after the last node in the list, it should be inserted just before the sentinel (head) node.
I would also suggest the following change to the Node constructor, so that it defaults to making a self-reference when the second and third argument are not provided:
class Node:
def __init__(self, value, nxt=None, prev=None):
self.data = value
self.next = nxt or self
self.prev = prev or self
And make good use of those parameters when you do pass arguments for them:
class DoublyList:
def __init__(self, c):
self.head = Node(None)
for i in c:
store = Node(i, self.head, self.head.prev)
store.prev.next = store.next.prev = store
The following code works:
class DoublyList:
def __init__(self, c):
self.head = Node(None,None,None) #instance variable
self.head.prev = self.head.next = self.head
for i in c:
store = Node(i, None, None)
store.prev = self.head.prev
store.next = self.head
self.head.prev = store
store.prev.next = store
print(store," ",store.prev)
if store.prev==self.head:
self.head.next=store #first node
There were 2 problems with your original code:
1:
You switched the prev and the next attribute. This is an easy fix: just change all `prev` attributes into `next` and vice versa.
2:
When executing the code after that, you might have noticed that there's nothing printed at all. This happens because your `self.head.next` remains setted to `self.head`, making your program not even start the while loop. To fix it, you've to find the first node in your for loop, and set `self.head.next` to it
class Node:
def __init__(self, item):
self.data = item
self.next = None
class LinkedList:
def __init__(self):
self.nodeCount = 0
self.head = None #Headnode(First node of LinkedList)
self.tail = None #Tailnode(Last node of LinkedList)
def getAt(self, pos): #pos = index number
if pos<=0 or pos>self.nodeCount:
return None
i = 1
curr = self.head
while i < pos:
curr = curr.next
i += 1
return curr
This is the code of LinkedList made by Python from DS class.
I have 2 questions from this code
When I learned C and C++, to make "Node class", I have to make Data field and Link(Pointer) field. And I store next Node's address(pointer) at Node's Link field. So I can move to next node. But at Python code, I don't know how node class's member's 'self.next' points next node. Which one is saved at the next field?
I do not inherit Node class at Linked List class. But how can I use Node class's member function 'self.next' at LinkedList class when I make getAt function?
Here is a simple implementation of Node and LinkedList classes in Python. The Node class has only 2 attributes: value and next. The LinkedList class only has one attribute: start. When an empty LinkedList is created, it has no start. All the interesting action occurs in the add_item_to_end() method. When the first item is added to a linked list, a node is created and assigned to start. When the second item is added, another node is created and assigned to the previously unoccupied next of the start node. When the third, fourth, ... nodes are added, the add method begins at the start of LinkedList and goes through all consecutively linked nodes until it reaches a node that has no next, then it set the next of that node to the node being added.
class Node:
def __init__(self, value = None, next = None):
self.value = value
self.next = next
class LinkedList:
def __init__(self, start = None):
self.start = start
def add_item_to_end(self, item):
my_node = Node(value=item)
if self.start == None:
self.start = my_node
else:
p = self.start
while p.next:
p = p.next
p.next = my_node
#The following method is just to visualize the linked list.
#It is not necessary for the functioning of the list:
def toList(self):
result = []
if self.start:
p = self.start
while p is not None:
result.append(p.value)
p = p.next
return result
#example runs
my_ll = LinkedList()
print(my_ll.toList())
#output: []
my_ll.add_item_to_end("bread")
print(my_ll.toList())
#output: ['bread']
my_ll.add_item_to_end("milk")
print(my_ll.toList())
#output: ['bread', 'milk']
I learned about linked-lists today. I learned how to insert and remove nodes from them. In the following code, it teaches me how to insert nodes with three distinct functions: at beginning (the head node), in between and at the end. However, they teach me how to remove the node in and single function. I don't find the code in the remove function to be very clear. Can anyone help make an easier to understand code under the remove function? Is there a way to make it into three functions just like the inserting ones? I'm open to any suggestion or explanation. Thanks in advance.
Here's my code:
class Node:
def __init__(self, data=None):
self.data = data
self.nextnode = None
class LinkedList:
def __init__(self):
self.headnode = None
def printlist(self):
node = self.headnode
while node is not None:
print (node.data)
node = node.nextnode
def atbegining(self,new_node):
new_node.nextnode = self.headnode
self.headnode = new_node
# Function to add newnode
def AtEnd(self, newnode):
if self.headnode is None:
self.headnode = newnode
return
node = self.headnode
while(node.nextnode):
node = node.nextnode
node.nextnode=newnode
# Function to add node
def Inbetween(self,preNode,newNode):
if preNode is None:
print("The mentioned node is absent")
return
newNode.nextnode = preNode.nextnode
preNode.nextnode = newNode
# Function to remove node
def RemoveNode(self, RemoveVal):
node = self.headnode
if (node is not None):
if (node.data == RemoveVal):
self.headnode = node.nextnode
node = None
return
while (node is not None):
if node.data == RemoveVal:
break
prevnode = node
node = node.nextnode
if (node == None):
return
prevnode.nextnode = node.nextnode
node = None
list1 = LinkedList()
list1.headnode = Node("Mon")
n2 = Node("Tue")
n3 = Node("Wed")
# Link first Node to second node
list1.headnode.nextnode = n2
# Link second Node to third node
n2.nextnode = n3
n4 = Node("Sun")
n5 = Node("Tur")
n6 = Node("Newdate")
list1.atbegining(n4)
list1.AtEnd(n5)
list1.Inbetween(list1.headnode,n6)
list1.RemoveNode("Newdate")
list1.printlist()
RemoveNode is complicated by the fact that there are two structurally distinct kinds of LinkedLists: one whose head is None, and one whose head is not None. You can fix this by making sure every LinkedList contains at least one node. This is typically referred to as a dummy node, and you can use this node to store metadata (such as the length of the list).
The Node class itself does not change.
class Node:
def __init__(self, data=None):
self.data = data
self.nextnode = None
The LinkedList, however, simplifies by creating a dummy node. This provides
the guarantee that every node that stores real data is point to by another node.
class LinkedList:
def __init__(self):
self.headnode = Node(0)
def insert(self, preNode, newNode):
newNode.nextnode = preNode.nextnode
preNode.nextnode = newNode
self.headnode.data += 1
def append(self, newNode):
curr = self.headnode
while curr.nextNode is not None:
curr = curr.nextNode
self.insert(curr, newNode)
def prepend(self, newNode):
self.insert(self.headnode, newNode)
def _find_before(self, val):
pre = self.headnode
while pre.nextnode is not None:
curr = pre.nextnode
if curr.data == val:
return pre
pre = curr
def remove(self, RemoveVal):
pre = self._find_before(RemoveVal)
if pre is None:
return
pre.nextnode = pre.nextnode.nextnode
self.headnode.data -= 1
This simplifies all three insertions. The general case can always apply, since there is always a node that comes before the node you insert. append and prepend are simple wrappers that find the appropriate node to pass to insert.
Likewise, remove simply finds the node before the given value, and if the search succeeds, handles updating the prior node's nextnode attribute.
insert and remove also update the size of the list stored in the dummy node.
A find method becomes a simple wrapper around _find_before; if you find a node before the value you are looking for, just return the node that follows it.
I think that an alternative design will make the code much clearer. Consider for example the following:
class Node:
def __init__(self, data=None):
self.data = data
self.nextnode = None
def printlist(self):
print(self.data)
if self.nextnode is not None:
self.nextnode.printlist()
def push(self, node):
node.nextnode = self
return node
def insertafter(self, node):
node.nextnode = self.nextnode
self.nextnode = node
return self
def append(self, node):
lastnode = self
while lastnode.nextnode is not None:
lastnode = lastnode.nextnode
lastnode.nextnode = node
return self
def remove(self, value):
prev = None
walk = self
while walk is not None:
if walk.data == value:
if prev is None:
return walk.nextnode
else:
prev.nextnode = walk.nextnode
return self
else:
prev = walk
walk = walk.nextnode
return self
list1 = Node("Mon")
n2 = Node("Tue")
n3 = Node("Wed")
# Link first Node to second node
list1 = list1.insertafter(n2)
# Link second Node to third node
n2 = n2.insertafter(n3)
n4 = Node("Sun")
n5 = Node("Tur")
n6 = Node("Newdate")
list1 = list1.push(n4)
list1 = list1.append(n5)
list1 = list1.insertafter(n6)
list1 = list1.remove("Newdate")
list1.printlist()
The main idea is that a Node is the linked list. As long as you have the head of the list kept in a variable, you can have access to the entire list, without the need for a separate data structure.
I'm a Noob, struggling to understand and implement a singly linked list, that adds items at the tail. I believe the only code that is not working is the add function, which I can't figure out the logic for. I believe I want to set the first node to be the head, and then insert each other element at the tail, changing the pointer for head to point to the 2nd item when adding it, then the pointer for the 2nd item to point to the third etc., but can't figure out how to go about coding that (to deal with an unknown number of strings, here 3 for simplicity.
strings = ["one", "two", "three"]
class Node:
def __init__(self,data,nextNode=None):
# populate the Node, with data and pointer
self.data = data
self.nextNode = nextNode
def getData(self):
# method to get value of this node
return self.data
def setData(self,val):
# set value of node to val
self.data = val
def getNextNode(self):
# get the pointer to the next node
return self.nextNode
def setNextNode(self,val):
# set pointer to the next node
self.nextNode = val
class LinkedList:
def __init__(self, head = None, tail = None):
# initial properties of linked list, size 0
self.head = head
self.tail = tail
self.size = 0
def getSize(self):
# get size of linked list
return self.size
def addNode(self,data):
# Head should point to first node, which will have a value, and a Null pointer
if (self.size == 0):
newNode = Node(data, self.tail)
self.head.getNextNode() = newNode
else:
# All additional nodes should be inserted at tail, and with the pointers for the prior nodes changed to point to the new node
newNode = Node(data, self.tail)
self.tail = newNode
self.size += 1
return True
def printNode(self):
curr = self.head
while curr:
print(curr.data)#, curr.nextNode)
curr = curr.getNextNode()
mylist = LinkedList()
for i in strings:
mylist.addNode(i)
mylist.printNode()
# desired output: Head -> one --> two --> three/Tail
There were many little mistakes, please find them in code below. And let me know if you don't understand something.
One important change is a new node shouldn't have access to its next node. Its already the last node, so there can't be any node next to it. Also please pay close attention to else block of addNode function.
strings = ["one", "two", "three","four","five"]
class Node:
def __init__(self,data):
# populate the Node, with data and pointer
self.data = data
self.nextNode = None
def getData(self):
# method to get value of this node
return self.data
def setData(self,val):
# set value of node to val
self.data = val
def getNextNode(self):
# get the pointer to the next node
return self.nextNode
def setNextNode(self,val):
# set pointer to the next node
self.nextNode = val
class LinkedList:
def __init__(self, head = None, tail = None):
# initial properties of linked list, size 0
self.head = head
self.tail = tail
self.size = 0
def getSize(self):
# get size of linked list
return self.size
def addNode(self,data):
# Head should point to first node, which will have a value, and a Null pointer
if (self.size == 0):
self.head = Node(data)
self.tail = self.head
self.size = 1
else:
# All additional nodes should be inserted at tail, and with the pointers for the prior nodes changed to point to the new node
newNode = Node(data)
self.tail.nextNode = newNode
self.tail = newNode
self.size += 1
return True
def printNode(self):
curr = self.head
while curr:
print(curr.data)#, curr.nextNode)
curr = curr.getNextNode()
mylist = LinkedList()
for i in strings:
mylist.addNode(i)
mylist.printNode()
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!