I need to implement this insert
function in my doubly linked list and I'm having trouble getting it to properly insert elements at given indexes. I am able to add an element into an empty list object, but when I attempt to add a new node at the last node, I get an error saying:
'NoneType' object has no attribute 'setPrev'
I understand what this error means and have tried shifting my function around to avoid this error and get the right output, but to no avail.
Question: How can I fix this insert function in order to allow it to add nodes in all cases?
class DLLNode:
def __init__(self,initdata):
self.data = initdata
self.next = None
self.prev = None
def __str__(self):
return str(self.data)
def getData(self):
return self.data
def getNext(self):
return self.next
def getPrev(self):
return self.prev
def setData(self, new_data):
self.data = new_data
def setNext(self, new_next):
self.next = new_next
def setPrev(self, new_prev):
self.prev = new_prev
class DLL:
""" Class representing a doubly-linked list. """
def __init__(self):
""" Constructs an empty doubly-linked list. """
self.head = None
self.size = 0
def __str__(self):
""" Converts the list into a string representation. """
current = self.head
rep = ""
while current != None:
rep += str(current) + " "
current = current.getNext()
return rep
def isEmpty(self):
""" Checks if the doubly-linked list is empty. """
return self.size <= 0
def insert(self, item, index):
""" Inserts a node at the specified index. """
# Construct node.
current = self.head
n = DLLNode(item)
# Check index bounds.
if index > self.size:
return 'index out of range'
# If the list is empty...
if self.isEmpty():
self.head = n
self.head.setPrev(self.head)
# If the index is the first node...
if index == 0:
n.setNext(self.head)
self.head = n
if self.size == 0:
self.prev = n
# If the index is the last node...
elif index == self.size:
n.next.setPrev(n)
# If the index is any other node...
else:
if current == None:
n.setPrev(self.prev)
self.prev.setNext(n)
self.prev = n
else:
n.setNext(current)
n.getPrev().setNext(n)
current.setPrev(n.getPrev())
n.setPrev(n)
self.size += 1
A testcase is the following scenario:
l = DLL()
l.insert(88, 0)
l.insert(99, 1)
l.insert(77, 2)
l.insert(55, 3)
l.insert(34, 1)
l.insert(3, 0)
l.insert(15, 6)
l.insert(100, 8)
print("list after inserts", l)
output is as follows:
Index out of range.
list after inserts 3 88 34 99 77 55 15 """
The problem is that n
is a DLLNode
you construct yourself. By default prev
and next
are set to Null
; therefore you cannot call any methods on them.
def insert(self, item, index):
""" Inserts a node at the specified index. """
# Construct node.
current = self.head
n = DLLNode(item)
# Check index bounds.
if index > self.size:
return 'index out of range'
# If the list is empty...
if self.isEmpty():
self.head = n
self.head.setPrev(self.head)
else : #added else case to prevent overlap
for x in range(0,index-1): #Obtain the current
current = current.next #move to the next item
# If the index is the first node...
if index == 0:
n.setNext(self.head)
self.head = n
if self.size == 0:
self.prev = n
# If the index is the last node...
elif index == self.size:
current.setNext(n) #set n to be the next of current
n.setPrev(current) #set current to be the previous of n
# If the index is any other node...
else:
n.setNext(current.next)
n.setPrev(current)
if current.next != None :
current.next.setPrev(n)
current.setNext(n)
self.size += 1
The last situation works as follows:
/------\|
C N X
|\------/
with C
the current
X the
next of
current and
N the
n (new node). First we set the
(new node). First we set the
prev and
next of
n`:
/------\|
C <--N-->X
|\------/
Now we check whether X
actually is a real node (although this is strictly not necessary, since "last nodes" are handled above). If X
is not None
, we set the prev
of X
to N
:
/------\|
C <--N-->X
|\-/
Finally we do not longer need C
to point to X
(otherwise we could not call functions of X
), so we set the next
of C
to N
:
/--\|
C <--N-->X
|\-/
Can you provide test data to test if the implementation works correctly?
I believe the problem is here
elif index == self.size:
n.next.setPrev(n)
When insert at the last element, you need to traverse to the current last element say last
. Assume you did that you can do
elif index == self.size:
last.setNext(n)
n.setPrev(last)
n.setNext(head) #only if this list is also circular
self.size++
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.