Страницы

Поиск по вопросам

Показаны сообщения с ярлыком двусвязный-список. Показать все сообщения
Показаны сообщения с ярлыком двусвязный-список. Показать все сообщения

пятница, 24 января 2020 г.

Python - NameError (двунаправленный связный список)

#python #двусвязный_список


Правильно ли я реализую двунаправленный связный список и, если да, то как исправить
ошибку?

class Cell:
    def __init__(self, value, name, prev, next):
        self.value = value
        self.name = name
        self.prev = prev
        self.next = next

E = Cell(5, "E", D, None)
D = Cell(4, "D", C, E)
C = Cell(3, "C", B, D)
B = Cell(2, "B", A, C)
A = Cell(1, "A", None, B)



  NameError: name 'D' is not defined

    


Ответы

Ответ 1



Вы на правильном пути, однако если конструктор списка будет принимать и предыдущую и следующую вершины, то возникнет циклическая зависимость. Возможным решением может быть убирание prev и next из конструктора и вынос их установки в отдельный метод: class Cell: def __init__(self, value, name): self.value = value self.name = name def set_prev_and_next(self, prev, next): self.prev = prev self.next = next A = Cell(1, 'A') B = Cell(2, 'B') C = Cell(3, 'C') D = Cell(4, 'D') E = Cell(5, 'E') A.set_prev_and_next(E, B) B.set_prev_and_next(A, C) C.set_prev_and_next(B, D) D.set_prev_and_next(C, E) E.set_prev_and_next(D, A) Однако в таком случае вам нужно будет каждый раз ручками заботиться о том, чтобы значения prev и next были согласованы. Например, если вы захотите вставить элемент в середину списка, то вам нужно будет вызвать метод set_prev_and_next у трёх элементов: вставляемого, предыдущего и следующего. Гораздо лучшим вариантом будет написать метод вроде insert_after, который будет вставлять элемент после некоторого элемента и сам обрабатывать согласованность значений prev и next. Например, так: class Cell: def __init__(self, value, name): self.value = value self.name = name self.prev = None self.next = None def insert_after(self, cell): if self.next is None: cell.prev = self cell.next = self self.prev = cell self.next = cell else: cell.prev = self cell.next = self.next self.next = next cell.next.prev = cell A = Cell(1, 'A') B = Cell(2, 'B') C = Cell(3, 'C') D = Cell(4, 'D') E = Cell(5, 'E') B.insert_after(A) C.insert_after(B) D.insert_after(C) E.insert_after(D)

Ответ 2



У Вас не получится вызвать переменную до ее определения, необходимо изменить порядок,чтобы интерпретатор знал куда вы обращаетесь, так работать не будет E = Cell(5, "E", D, None) D = Cell(4, "D", C, E) C = Cell(3, "C", B, D) B = Cell(2, "B", A, C) A = Cell(1, "A", None, B) можно попробовать изменить логику, я могу ошибаться и буду благадарен за правки более опытных участников class Constr(object): def __init__(self, value, name, prev=None): self.value = value self.name = name self.prev = prev self.next = None def add_next(self, obj): self.next = obj def show(self): answer = dict(name=self.name, value=self.value, prev=self.prev, next=self.next) return answer class Contain(object): def __init__(self): self.all_obj = [] def update_obj(self, value, name): if not self.all_obj: new = Constr(value, name) self.all_obj.append(new) else: update_obj = self.all_obj[-1] new_obj = Constr(value, name, prev=update_obj) update_obj.add_next(new_obj) self.all_obj.append(new_obj) return True def get_list(self): if self.all_obj: return [i.show() or None for i in self.all_obj] return [] test = Contain() test.update_obj(1, 'hello') test.update_obj(2, 'world') test.update_obj(3, '!') test.get_list()

воскресенье, 7 июля 2019 г.

Удаление элемента двусвязного списка C++

При успешном удалении должно возвращать true, но почему то всегда возвращает фолс. Вот класс:
struct Num { int number; bool ring; Num *next, *prev; };
class List { protected : Num *head, *tail;
public : List():head(NULL),tail(NULL){} ~List(); int genNum(); void Add(int x); bool Remove(int i); };
И моя попытка переделать удаление :
bool List::Remove(int idx) { Num *current = head; Num *temp = nullptr; int i = 0;
while(current->next != NULL) { if(i != idx) { current = current->next; i++; }
else { temp = current->prev; current->prev = current->next; current->next->prev = temp;
return true; } }
return false; }


Ответ

Я только исправлю часть кода, что посчитал неправильным.
else { if (idx == 1) { temp = head; head = current; } else { temp = current->prev; // указывает на узель, который должен удаляться current->prev = temp->prev; current->prev->next = current; } delete temp; return true; }

понедельник, 18 марта 2019 г.

Python - NameError (двунаправленный связный список)

Правильно ли я реализую двунаправленный связный список и, если да, то как исправить ошибку?
class Cell: def __init__(self, value, name, prev, next): self.value = value self.name = name self.prev = prev self.next = next
E = Cell(5, "E", D, None) D = Cell(4, "D", C, E) C = Cell(3, "C", B, D) B = Cell(2, "B", A, C) A = Cell(1, "A", None, B)
NameError: name 'D' is not defined


Ответ

Вы на правильном пути, однако если конструктор списка будет принимать и предыдущую и следующую вершины, то возникнет циклическая зависимость. Возможным решением может быть убирание prev и next из конструктора и вынос их установки в отдельный метод:
class Cell: def __init__(self, value, name): self.value = value self.name = name
def set_prev_and_next(self, prev, next): self.prev = prev self.next = next
A = Cell(1, 'A') B = Cell(2, 'B') C = Cell(3, 'C') D = Cell(4, 'D') E = Cell(5, 'E')
A.set_prev_and_next(E, B) B.set_prev_and_next(A, C) C.set_prev_and_next(B, D) D.set_prev_and_next(C, E) E.set_prev_and_next(D, A)
Однако в таком случае вам нужно будет каждый раз ручками заботиться о том, чтобы значения prev и next были согласованы. Например, если вы захотите вставить элемент в середину списка, то вам нужно будет вызвать метод set_prev_and_next у трёх элементов: вставляемого, предыдущего и следующего. Гораздо лучшим вариантом будет написать метод вроде insert_after, который будет вставлять элемент после некоторого элемента и сам обрабатывать согласованность значений prev и next. Например, так:
class Cell: def __init__(self, value, name): self.value = value self.name = name self.prev = None self.next = None
def insert_after(self, cell): if self.next is None: cell.prev = self cell.next = self self.prev = cell self.next = cell else: cell.prev = self cell.next = self.next self.next = next cell.next.prev = cell
A = Cell(1, 'A') B = Cell(2, 'B') C = Cell(3, 'C') D = Cell(4, 'D') E = Cell(5, 'E')
B.insert_after(A) C.insert_after(B) D.insert_after(C) E.insert_after(D)