Как реализовать связанный список с помощью ООП? - PullRequest
0 голосов
/ 24 декабря 2018

Я пытаюсь реализовать связанный список, используя ООП и закрытые переменные.Тем не менее, я получаю 'str' object has no attribute 'get_data' при вызове метода display класса LinkedList.Кроме того, я чувствую, что метод add также не является правильным.

Когда я печатаю self.__head и self.__tail в add(), код никогда не входит в остальную часть и выдает:

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()

Ответы [ 3 ]

0 голосов
/ 25 декабря 2018

Итак, я разработал ответ на мою проблему.Спасибо всем за помощь.Я до сих пор не уверен в этом:

Я знаю, что Python по умолчанию не имеет закрытых переменных по сравнению с такими языками, как Java, но я считаю, что Python подразумевает соблюдение соглашений, а '__' - соглашение дляскажите другому разработчику, что эта конкретная сущность является частной.

Однако в моем случае я не смог бы получить доступ к данным и следующим атрибутам класса Node, образующим класс LinkedList, и наоборот, напрямую, когда имя разрешается. _Classnmae__attribute_name при использовании закрытых переменных.Поэтому лучшее решение - использовать геттеры и сеттеры, потому что они предназначены именно для них.

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)

Алгоритм :

add (data)

  1. Создать новый узел с данными

  2. Если связанный список пуст (головной узел не ссылается на какой-либо другой узел), сделайте головной узел и хвостовой узел ссылкой на новый узел

  3. В противном случае,

    a.Сделайте ссылку на хвостовой узел ссылкой на новый узел

    b.Вызовите новый узел как хвостовой узел

0 голосов
/ 25 декабря 2018

Вот способ сделать это более кратко, используя несколько «хитростей» реализации односвязных списков, о которых я знаю.

Связанный список всегда состоит по крайней мере из одного sentinel узел, который автоматически создается и сохраняется в атрибуте экземпляра self._tail.Наличие этого имеет несколько преимуществ.

  1. Зная, где находится tail, можно быстро и легко добавлять что-либо в конец.
  2. Список никогда не бывает пустым, так что особыйдело не нужно проверять.Хороший побочный эффект этого означает, что для итерации по элементам списка требуется только следовать self._next, пока он не станет сторожевым узлом - одно условное выражение.

Другой «трюк» заключается в добавленииновый последний элемент справа перед текущим сторожевым узлом - что медленно звучит в односвязном списке, потому что кажется, что требуется изменить 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()

Вывод:

adding: Sugar
adding: Milk
adding: Tea
adding: Biscuits

Linked list contents:
  Sugar
  Milk
  Tea
  Biscuits
0 голосов
/ 24 декабря 2018

Это кажется подозрительным:

self.__head = Node(data).get_data()

Учитывая, что вы даже больше не ссылаетесь на узел ... Затем пытаетесь вызвать методы объекта Node.Даже в этом случае ваша реализация по-прежнему неверна.

Я уверен, что есть другие проблемы, но вы можете зайти в Google или сделать собственный проект / домашнюю работу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...