#9. Делаем односвязный список на С++ | Структуры данных

  Рет қаралды 21,442

selfedu

selfedu

Жыл бұрын

Обучающий курс: stepik.org/a/134212
Инфо-сайт: proproprogs.ru/structure_data
Пример реализации односвязного списка на С++.

Пікірлер: 58
@user-ni1ty8ul4l
@user-ni1ty8ul4l 4 ай бұрын
Спасибо огромное за такой ценный концентрат знаний!🏆🎁 Удивительно, что на незнакомом мне С++ до меня наконец-то дошло понимание связанных списков!
@user-bx1ro9iu8b
@user-bx1ro9iu8b 4 ай бұрын
огромное спасибо за подробности и ваш подход. Видео о более правильном построении такого списка есть на ютубе и люди часами настраивают его с учетом всех принципов ООП, но получить первый уровень понимания как строить такие списки без высочайшего понимания C++ на таких роликах не выйдет. А у вас достаточно маленьких знаний и желания Ещё раз спасибо
@ficha4741
@ficha4741 Жыл бұрын
Вот такой момент: сколько смотрел видео по тегам односвязный список, будь-то СимплКод или преподы из МФТИ, ничего годного найти не удалось до твоего канала. Урок реально помог! Спасибо!
@ficha4741
@ficha4741 Жыл бұрын
Только один вопрос: что означает изначальное Node* внутри класса Node? Создание большого указателя, по которому может идти перемещение посредством this? Как называется этот элемент синтаксиса?
@selfedu_rus
@selfedu_rus Жыл бұрын
Спасибо! Node - это класс (тип данных), а Node *head - это объявление указателя типа Node. То есть, head - это обычная переменная-указатель внутри класса.
@ficha4741
@ficha4741 Жыл бұрын
@@selfedu_rus благодарю за ответ
@user-ub9ig4uf9l
@user-ub9ig4uf9l Жыл бұрын
Ну явно тупенький
@talisman1104
@talisman1104 Ай бұрын
CodeBlog норм
@Anilid.
@Anilid. 6 ай бұрын
ОГРОМНОЕ СПАСИБО! всё очень понятно и доходчиво! З.ы. компилируется всё нормально Visual Studio Community 2022 Версия 17.7.5
@fil-os-of
@fil-os-of Жыл бұрын
Вот рабочий вариант: #include using namespace std; // Making a node struct containing an int data and a pointer // to next node struct Node{ int data; Node *next; // Parameterised constructor with default argument Node(int val=0) :data(val),next(nullptr){} // Parameterise constructor Node(int val, Node *tempNext):data(val),next(tempNext){} }; class LinkedList{ // Head pointer Node* head; public: // default constructor. Initializing head pointer LinkedList():head(nullptr){} // inserting elements (At start of the list) void insert(int val){ // make a new node Node* new_node = new Node(val); // If list is empty, make the new node, the head if (head == nullptr){ head = new_node; } // else, make the new_node the head and its next, the previous // head else{ new_node->next = head; head = new_node; } } // loop over the list. return true if element found bool search(int val){ Node* temp = head; while(temp != nullptr){ if (temp->data == val) return true; temp = temp->next; } return false; } void remove(int val){ Node* temp = head; // If the head is to be deleted if (temp != nullptr && temp->data == val){ head = temp->next; delete temp; return; } // Else loop over the list and search for the node to delete else{ Node* curr = head; while(temp != nullptr && temp->data != val){ // When node is found, delete the node and modify the pointers curr = temp; temp = temp->next; } // If values is not found in the linked list if(!temp){ cout next; delete temp; } } void display() { Node* temp = head; while(temp != nullptr){ cout data next; } cout
@nebesnistalker
@nebesnistalker Ай бұрын
Хотелось бы пример с односвязным списком на Питоне увидеть, С++ не знаю от слова совсем
@mingboevnurullo
@mingboevnurullo 7 ай бұрын
legend
@newtonacademy77
@newtonacademy77 4 ай бұрын
Вопрос автору! Не является ли излишеством в методе getAt() в условии цикла while вставлять проверку node? Ведь всё равно когда обход списка дойдёт до последнего элемента node->next станет NULL и цикл завершит свою работу. Или может логической необходимости в этой проверке нет, и она прописана для подстраховки?
@selfedu_rus
@selfedu_rus 4 ай бұрын
Это привычка делать "основательные" проверки, не полагаясь на другие, т.к. они (другие) могут в будущем поменяться.
@nikitaefremov3147
@nikitaefremov3147 6 ай бұрын
Добрый день! Я конечно не знаком с C++, но примерно все уловил, но не понял почему когда вызывали метод insert в самом конце и указывая индекс 0 он вставлял значения после 1, а не перед?
@user-ee1lx1pe7n
@user-ee1lx1pe7n Жыл бұрын
Спасибо большое! Очень жаль, что нет кода на гитхабе
@gretings
@gretings Жыл бұрын
Поправьте, пожалуйста, если не прав: в методе Erase, в случае, если удалённый элемент node являлся tail, разве теперь tail не должен быть right, а не left?
@selfedu_rus
@selfedu_rus Жыл бұрын
Если мы удаляем последний элемент, то tail должен сдвигаться влево, т.к. справа ничего нет.
@user-sv8oq5wd3q
@user-sv8oq5wd3q 8 ай бұрын
Автор пише код в Visual Studio. Я повторяю код. в CLion, всё работает.
@fores_069
@fores_069 Жыл бұрын
Реализация на python, может кому нужно class Node: def __init__(self, data): self.data = data self.next = None class LinkedList: def __init__(self): self.head = None self.tail = None def is_empty(self): return self.head is None def push_back(self, data): new_node = Node(data) if self.is_empty(): self.head = self.tail = new_node else: self.tail.next = new_node self.tail = new_node def push_front(self, data): new_node = Node(data) if self.is_empty(): self.head = self.tail = new_node else: new_node.next = self.head self.head = new_node def erase(self, data): if self.is_empty(): return if self.head.data == data: self.head = self.head.next return current = self.head while current.next: if current.next.data == data: print(current.next.next) current.next = current.next.next return current = current.next def search(self, data): current = self.head while current: if current.data == data: return True current = current.next return False def print_list(self): current = self.head while current: print(current.data, end=" -> ") current = current.next print("None") linked_list = LinkedList() linked_list.push_back(12) linked_list.push_back(103) linked_list.push_back(11) linked_list.push_back(43) linked_list.push_back(12) linked_list.push_back(23) print(linked_list.print_list())
@uralbeking
@uralbeking 11 ай бұрын
Реализация не соответствует примеру на видео, потому что метод erase удаляет node по первому попавшемуся значению, а не по индексу node и ещё нету метода insert который тоже принимает индекс как аргумент
@andreyf7035
@andreyf7035 Жыл бұрын
А как тогда вставлять элементы в начало такого списка с помощью метода insert, если при вставке по нулевому индексу вставляется на первый?
@selfedu_rus
@selfedu_rus Жыл бұрын
нужно переписать, чтобы индекс соответствовал вставляемому элементу (считайте это домашним заданием), а вообще вставку первого и последнего лучше выполнять методами push_front() и push_back() они оптимизированы под это
@andreyf7035
@andreyf7035 Жыл бұрын
@@selfedu_rus понял спасибо!
@sype1680
@sype1680 Жыл бұрын
Я так сделал: if (k > 0) { Node* left = getAt(k - 1); if (left == NULL) return; Node* node = new Node(data); node->next = left->next; if (left->next == NULL) tail = node; left->next = node; } else if (k == 0) push_front(data);
@sype1680
@sype1680 Жыл бұрын
Лучше сделать через switch case, чтобы два раза не вычислять k, но разница мизерная. А на вопрос: "почему else if, а не else" - чтобы при передаче отрицательного индекса фукция ничего не выполняла.
@user-gs1cx6ok7h
@user-gs1cx6ok7h Жыл бұрын
а чем отличается эта версия видео №9 от предыдущей?
@selfedu_rus
@selfedu_rus Жыл бұрын
упоминаю об std::forward_list
@roninn6127
@roninn6127 9 ай бұрын
почему мы для pop_font написали ~OneLinkedList() { while (head!= NULL) pop_front(); } а для pop_back не написали что то подобное на цикл
@user-cw2si2xt3t
@user-cw2si2xt3t 8 ай бұрын
~OneLinkedList(){...} Это деструктор класса. Он не имеет отношение к pop_front. Просто в нем использовали pop_front можно было и pop_back использовать
@fil-os-of
@fil-os-of Жыл бұрын
А что делать, если у меня данные не помещаются в double?
@user-lg7pq1od3b
@user-lg7pq1od3b 9 ай бұрын
Есть же вроде double double
@user-cq4kq3nc4u
@user-cq4kq3nc4u 8 ай бұрын
коллега, как пофиксил?
@fil-os-of
@fil-os-of 8 ай бұрын
@@user-cq4kq3nc4u максимальный размер оперируемого блока можно определить глобально в соответствии с архитектурой аппаратной платформы
@fil-os-of
@fil-os-of Жыл бұрын
В моём компиляторе не работает void
@selfedu_rus
@selfedu_rus Жыл бұрын
странно, старый значит? раньше его не было, но уже с ANSI C появился
@isded1681
@isded1681 Жыл бұрын
14:50 разве это не логическое "и"?
@selfedu_rus
@selfedu_rus Жыл бұрын
цикл завершится, если n != k или пока не дойдем до конца списка (говорится о завершении цикла, а не об условии его работы)
@Al-sk2nw
@Al-sk2nw Жыл бұрын
Зачем в классе дважды указывается public?
@selfedu_rus
@selfedu_rus Жыл бұрын
так принято, первый - для переменных, второй - для методов
@sergeyworm1476
@sergeyworm1476 Жыл бұрын
По мне так это дело стиля и вкуса. Если честно, я не знаю принято ли так где-то, но так описание класса выглядит более структурированным.
@fil-os-of
@fil-os-of Жыл бұрын
А что, без классов создать односвязный список нельзя?
@selfedu_rus
@selfedu_rus Жыл бұрын
почему бы и не с классами?
@alexmercer7446
@alexmercer7446 11 ай бұрын
можно через struct
@fil-os-of
@fil-os-of Жыл бұрын
С++ подходит для демонстрации всех нюансов создания и работы с объектами в памяти компьютера, на мой взгляд, для этого лучше подойдёт язык ассемблера, а реализацию односвязного списка и стека на его основе можно создать на любом языке программирования.
@alex6161
@alex6161 Жыл бұрын
C++ так или иначе понимают все, и он ближе к ассемблеру чем прочие языки. Примеры на ассемблере будут непонятны широкому кругу новичков.
@fil-os-of
@fil-os-of Жыл бұрын
@@alex6161 новички вообще ничего не понимают, ни в C++ ни тем более в языке ассемблера, который специфичен в зависимости от архитектуры платформы. А те кто понимают не смотрят такие видео на youtube. Я не поленился и посмотрел весь материал относящийся к с++ на этом канале и признаться сделал это с трудом и почти ничего из увиденного толком не запомнил и не понял зачем.
@alex6161
@alex6161 Жыл бұрын
@@fil-os-of ну я вот новичок, решил golang изучить, но курса по структурам на go я не нашел на русском языке, так что вот смотрю это, и довольно понимаю (ровно то что говорят, эти примеры и синтаксис языка), тонкости языка в примерах не используются. Гарвардский курс тоже с примерами на с++, но там именно учат этому языку во всех подробностях, что мне не надо. А вот от слова ассемблер мне страшно.
@fil-os-of
@fil-os-of Жыл бұрын
@@alex6161 каждому своё, мне лично ничего не страшно. Просто в языке ассемблера ещё меньше абстракций и простые функции приходится описывать в рамках машинной логики. Инструментарий скудный, набор объектов не велик, вот и получается куча рутинного текста решающего простые задачи. Есть ли сложности, конечно, приходится читать документацию к платформе и к реализации языка.
@fil-os-of
@fil-os-of Жыл бұрын
Всё, что нужно знать про приведенный пример: main.cpp:70:5: error: expected unqualified-id before ‘for’ 70 | for (;node->next != tail; node = node->next); | ^~~ main.cpp:70:11: error: ‘node’ does not name a type; did you mean ‘Node’? 70 | for (;node->next != tail; node = node->next); | ^~~~ | Node main.cpp:70:31: error: ‘node’ does not name a type; did you mean ‘Node’? 70 | for (;node->next != tail; node = node->next); | ^~~~ | Node main.cpp:71:5: error: ‘node’ does not name a type; did you mean ‘Node’? 71 | node->next = NULL; | ^~~~ | Node main.cpp:72:5: error: expected unqualified-id before ‘delete’ 72 | delete tail; | ^~~~~~ main.cpp:73:5: error: ‘tail’ does not name a type 73 | tail = node; | ^~~~ main.cpp: In destructor ‘SinglyLinkedList::~SinglyLinkedList()’: main.cpp:32:30: error: ‘pop_front’ was not declared in this scope; did you mean ‘push_front’? 32 | while (head != NULL) pop_front(); | ^~~~~~~~~ | push_front main.cpp:34:25: warning: empty parentheses were disambiguated as a function declaration [-Wvexing-parse] 34 | double pop_front(){ | ^~ main.cpp:34:25: note: remove parentheses to default-initialize a variable 34 | double pop_front(){ | ^~ | -- main.cpp:34:25: note: or replace parentheses with braces to value-initialize a variable main.cpp:34:27: error: a function-definition is not allowed here before ‘{’ token 34 | double pop_front(){ | ^ main.cpp: In member function ‘double SinglyLinkedList::push_back(double)’: main.cpp:52:5: warning: no return statement in function returning non-void [-Wreturn-type] 52 | } | ^ main.cpp: In member function ‘double SinglyLinkedList::push_front(double)’: main.cpp:59:5: warning: no return statement in function returning non-void [-Wreturn-type] 59 | } | ^ main.cpp: In member function ‘double SinglyLinkedList::pop_back()’: main.cpp:62:27: error: return-statement with no value, in function returning ‘double’ [-fpermissive] 62 | if (tail == NULL) return; | ^~~~~~ main.cpp:66:13: error: return-statement with no value, in function returning ‘double’ [-fpermissive] 66 | return; | ^~~~~~ main.cpp: In member function ‘double SinglyLinkedList::insert(int, double)’: main.cpp:88:27: error: return-statement with no value, in function returning ‘double’ [-fpermissive] 88 | if (left == NULL) return; | ^~~~~~ main.cpp:91:9: error: ‘left’ does not name a type 91 | left->next = node; | ^~~~ main.cpp: In member function ‘int SinglyLinkedList::erase(int)’: main.cpp:97:20: error: return-statement with no value, in function returning ‘int’ [-fpermissive] 97 | if (k < 0) return; | ^~~~~~ main.cpp:99:13: error: ‘pop_front’ was not declared in this scope; did you mean ‘push_front’? 99 | pop_front(); | ^~~~~~~~~ | push_front main.cpp:100:13: error: return-statement with no value, in function returning ‘int’ [-fpermissive] 100 | return; | ^~~~~~ main.cpp:103:27: error: return-statement with no value, in function returning ‘int’ [-fpermissive] 103 | if (node == NULL) return; | ^~~~~~
@mikug6735
@mikug6735 Жыл бұрын
А почему на пайтон не показали?)
@selfedu_rus
@selfedu_rus Жыл бұрын
в курсе ООП было и на С++ более подробно выходит
@mikug6735
@mikug6735 Жыл бұрын
@@selfedu_rus надо чекнуть, спасибо
@romangrigorovich5205
@romangrigorovich5205 Жыл бұрын
@@selfedu_rus а можно ссылку на видео? Курс ООП на Python? там много видео, в названиях вроде нигде не увидел упоминаний про списки.. а все просматривать в поисках нужной инфы - долго(
@selfedu_rus
@selfedu_rus Жыл бұрын
@@romangrigorovich5205 В этом курсе stepik.org/course/116336/
@romangrigorovich5205
@romangrigorovich5205 Жыл бұрын
@@selfedu_rus в виде задачи в курсе? я думал где-то в видео объяснение было. ну тогда ладно
@user-bo2ow7pq7i
@user-bo2ow7pq7i 9 ай бұрын
Это точно С++ а то синтаксис несколько отличается . По ходу я заметил что программа пишется в графредакторе а не Визуал студио и врядли скомпилируется .
@user-wc2hb9qo1u
@user-wc2hb9qo1u Жыл бұрын
Всё ооочень быстро, скомкано, ничего не понятно
1❤️
00:17
Nonomen ノノメン
Рет қаралды 4,5 МЛН
ИРИНА КАЙРАТОВНА - АЙДАХАР (БЕКА) [MV]
02:51
ГОСТ ENTERTAINMENT
Рет қаралды 8 МЛН
Односвязный список C#
32:12
SBeregovoyRU
Рет қаралды 11 М.
Всё об указателях в C++ за 20 минут
20:00
How To Learn Algorithms? Why? #codonaft
19:22
codonaft
Рет қаралды 562 М.
1❤️
00:17
Nonomen ノノメン
Рет қаралды 4,5 МЛН