我正在尝试使用OOP和私有变量来实现链表。但是,当我调用'str' object has no attribute 'get_data'
类的display
方法时,会得到 LinkedList
。另外,我觉得add
方法也不正确。
当我在self.__head
中打印self.__tail
和add()
时,代码从不输入else部分,而是输出:
Sugar Sugar
Milk Milk
Tea Tea
Biscuit Biscuit
下面是我的代码:
class LinkedList:
def __init__(self):
self.__head=None
self.__tail=None
def get_head(self):
return self.__head
def get_tail(self):
return self.__tail
def add(self,data): # Skeptical about it
if self.__tail is None:
self.__head=Node(data).get_data()
self.__tail = self.__head
print(self.__head,self.__tail)
else:
b=Node(data)
self.__tail= b.get_data()
self.__head = self.__tail
b.set_next(self.__tail)
self.__tail = b.get_next()
print(self.__head,self.__tail)
def display(self): # Gives the error
temp = self.__head
msg = []
c = Node(temp)
while (temp is not None):
print(temp.get_data())
msg.append(str(temp.get_data()))
temp = temp.get_next()
msg = ''.join(msg)
print(msg)
class Node:
def __init__(self,data):
self.__data=data
self.__next=None
def get_data(self):
return self.__data
def set_data(self,data):
self.__data=data
def get_next(self):
return self.__next
def set_next(self,next_node):
self.__next=next_node
list1=LinkedList()
list1.add("Sugar")
#print(list1.get_head())
#print("Element added successfully")
list1.add("Milk")
list1.add("Tea")
list1.add("Biscuits")
list1.display()
答案 0 :(得分:1)
这似乎令人怀疑:
self.__head = Node(data).get_data()
考虑到您甚至不再引用该节点...然后尝试调用Node对象的方法。即使那样,您的实现仍然是错误的。
我确定还有其他问题,但是您可以在Google上进行搜索或实际执行自己的项目/作业。
答案 1 :(得分:0)
因此,我已经解决了我的问题。谢谢大家的帮助。我仍然不清楚:
与Java之类的语言相比,我知道python在默认情况下不带有私有变量,但是我相信python是关于遵守约定的,并且'__'是告诉其他开发人员该特定实体是私有的约定。>
但是,在我的情况下,由于使用私有变量时名称解析为 _Classnmae__attribute_name ,因此我无法直接从LinkedList类访问Node类的数据和下一个属性,反之亦然。因此,更好的解决方案是使用getter和setter,因为这是它们的共同点。
def add(self,data):
#Remove pass and write the logic to add an element
new_node = Node(data)
if self.__head is None:
self.__head = self.__tail = new_node
else:
self.__tail.set_next(new_node)
self.__tail = new_node
def display(self):
#Remove pass and write the logic to display the elements
temp = self.__head
msg = []
c = Node(temp)
while (temp is not None):
msg.append(str(temp.get_data()))
temp = temp.get_next()
msg = ' '.join(msg)
print(msg)
算法:
添加(数据)
使用数据创建新节点
如果链接列表为空(头节点未引用任何其他节点), 使头节点和尾节点引用新节点
否则,
a。使尾节点的链接引用新节点
b。将新节点称为尾节点
答案 2 :(得分:0)
这是一种通过使用一些我所知道的单链接列表实现“技巧”来更简洁地实现此目的的方法。
一个链表总是由至少一个 sentinel 节点组成,该节点自动创建并存储在实例属性self._tail
中。拥有它有很多好处。
tail
的位置可以快速简便地添加内容。self._next
直到它成为前哨节点(一个条件表达式)即可。另一个“技巧”是在当前前哨节点之前 处添加新的最后一个元素时-在单链列表中听起来很慢,因为它似乎需要修改{{1 }}添加到其中一个。为了达到这样做的效果,但实际上却避免这样做,它要做的就是将现有前哨节点变成新的Node
所包含的内容,并使其成为Node
属性是它创建的新标记,以替换之前要重用的标记。
这如何帮助理解以下代码中发生的事情:
_next
输出:
class LinkedList:
def __init__(self):
self._tail = Node()
self._head = self._tail
def add(self, data):
""" Add an item to the end of the linked list. """
new_tail = Node()
self._tail.set_data(data) # Convert existing tail into a data node.
self._tail.set_next(new_tail)
self._tail = new_tail
print('adding:', data)
def display(self):
""" Traverse linked list and print data associated with each Node. """
print('\nLinked list contents:')
curr = self._head
while curr is not self._tail:
print(' ' + curr.get_data())
curr = curr.get_next()
class Node:
def __init__(self, data=None):
self._data = data
self._next = None
def get_data(self):
return self._data
def set_data(self, data):
self._data = data
def get_next(self):
return self._next
def set_next(self, next_node):
self._next = next_node
if __name__ == '__main__':
list1 = LinkedList()
list1.add("Sugar")
list1.add("Milk")
list1.add("Tea")
list1.add("Biscuits")
list1.display()