1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
//#Листинг #1 Узел списка Односвязные списки Borland C++ 3.1 #include <conio.h> #include <iostream.h> struct element //Структура с инфополями и адресным полем { int x; //Инфополе. значения из x будут передаваться в список element *Next; //Адресное поле }; int main() { clrscr(); //зачистка экрана от старой информации cin.get(); //чтобы окно не закрывалось сразу return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
//Листинг #2 Список Односвязные списки Borland C++ 3.1 #include <conio.h> #include <iostream.h> struct element //Структура с инфополями и адресным полем { int x; //Инфополе. значения из x будут передаваться в список element *Next; //Адресное поле }; class List //Класс Список { element *Head; //Указатель на последний активный элемент или просто голова списка public: List() {Head=NULL;} //Конструктор и инициализация указателя пустым значением ~List(); //Деструктор }; List::~List() //Деструктор вынесен за класс { while (Head!=NULL) //Пока по адресу не пусто { element *temp=Head->Next; //Временная переменная для хранения адреса следующего элемента delete Head; //Освобождаем адрес обозначающий начало Head=temp; //Меняем адрес на следующий } } int main() { clrscr(); cin.get(); return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
//Листинг #3 Односвязные списки Borland C++ 3.1 #include <conio.h> #include <iostream.h> struct element //Структура с инфополями и адресным полем { int x; //Инфополе. значения из x будут передаваться в список element *Next; //Адресное поле }; class List //Класс Список { element *Head; //Указатель на последний активный элемент или просто голова списка public: List() {Head=NULL;} //Конструктор и инициализация указателя пустым значением ~List(); //Деструктор. Далее он вынесен за класс void Add(int x); //Функция для добавления значений в список void Show(); //Функция для отображения списка на экране }; List::~List() //Деструктор вынесен за класс { while (Head!=NULL) //Пока по адресу не пусто { element *temp = Head->Next; //Временная переменная для хранения адреса следующего элемента delete Head; //Освобождаем адрес обозначающий начало Head = temp; //Меняем адрес на следующий } } void List::Add(int x) //Функция добавления элементов в список { element *temp = new element; //При каждом вызове выделяется память temp->x = x; //Записываем x в элемент структуры element (в x структуры element) temp->Next = Head; //Указываем, что след. элемент это объект по адресу Head Head = temp; //Указываем, что последний активный элемент это только что введенный } void List::Show() //Функция отображения списка на экране { element *temp = Head; //Определяем указатель, который изначально он равен адресу начала списка while (temp != NULL) //До тех пор пока не встретит пустое значение { cout << temp->x << " "; //Выведет элемент x из списка temp = temp->Next; //Указываем, что далее нам нужен следующий элемент } } int main() { clrscr(); cin.get(); return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
//Листинг #4 Односвязный список LIFO, использование Borland C++ 3.1 #include <conio.h> #include <iostream.h> struct element //Структура с инфополями и адресным полем { int x; //Инфополе. значения из x будут передаваться в список element *Next; //Адресное поле }; class List //Класс Список { element *Head; //Указатель на последний активный элемент или просто голова списка public: List() {Head = NULL;} //Конструктор и инициализация указателя пустым значением ~List(); //Прототип деструктора. Сам деструктор вынесен за класс void Add(int x); //Прототип функции добавления значений в список void Show(); //Прототип функцииотображения списка на экране }; List::~List() //Деструктор вынесен за класс { while (Head != NULL) //Пока по адресу не пусто { element *temp = Head->Next; //Временная переменная для хранения адреса следующего элемента delete Head; //Освобождаем адрес обозначающий начало Head = temp; //Меняем адрес на следующий } } void List::Add(int x) //Функция добавления элементов в список { element *temp = new element; //При каждом вызове выделяется память temp->x = x; //Записываем x в элемент структуры element (в x структуры element) temp->Next = Head; //Указываем, что след. элемент это объект по адресу Head Head = temp; //Указываем, что последний активный элемент это только что введенный } void List::Show() //Функция отображения списка на экране { element *temp=Head; //Определяем указатель, который изначально он равен адресу начала списка while (temp != NULL) //До тех пор пока не встретит пустое значение { cout << temp->x << " "; //Выведет элемент x из списка temp = temp->Next; //Указываем, что далее нам нужен следующий элемент } } int main() { clrscr(); int N; //Число элементов в список int x; //Элементы вводимые в список List lst; //Переменная, тип которой список cout << "N = "; cin >> N; //Указали сколько элементов вводить в список for (int i=0; i<N; i++) { cout << i+1 << ". x = "; cin >> x; //Ввод x с клавиатуры lst.Add(x); //Добавление элемента в список } lst.Show(); //Вывод списка на экран cin.ignore().get(); //Для того, чтобы окно сразу не закрывалось return 0; } |
======================================================================
======================================================================
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
//Листинг #5 Односвязный список LIFO, список студентов Borland C++ 3.1 #include <iostream.h> #include <string.h> #include <stdlib.h> /*СТРУКТУРА СТУДЕНТ*/ struct Student { char Name[20]; //Имя char NameLast[30]; //Фамилия int Age; //Возраст char School[30]; //Место учебы void Input(Student &student); //Функция ввода данных в структуру Student *Next; //Адрес на следующий элемент }; class List { Student *Head; //Указатель на начало списка public: List():Head(NULL){}; //Конструктор по умолчанию (Head=NULL) ~List(); //Прототип деструктора void Add(Student &student); //Прототип функции добавления элемента в список void Show(); //Прототип функции вывода списка на экран }; /*ФУНКЦИЯ ЗАПОЛНЕНИЯ ДАННЫХ ПО СТУДЕНТУ*/ void Student::Input(Student &student) { cout << endl; //Небольшой разрыв при каждом новом вводе cout << "Имя: "; cin.getline(Name,20); //Ввод имени cout << "Фамилия: "; cin.getline(NameLast,30); //Ввод фамилии cout << "Полных лет "; cin >> Age; //Ввод возраста cin.ignore(); //Игнорируем символ cout << "Где учится "; cin.getline(School, 30); //Ввод места учебы } List::~List() //Деструктор класса List { while (Head != NULL) //Пока по адресу есть хоть что-то { Student *temp = Head->Next; //Сразу запоминаем указатель на адрес следующего элемента структуры delete Head; //Освобождаем память по месту начала списка Head = temp; //Меняем адрес начала списка } } /*ФУНКЦИЯ ДОБАВЛЕНИЯ НОВОЙ СТРУКТУРЫ В СПИСОК*/ void List::Add(Student &student) { Student *temp = new Student; //Выделение памяти под новую структуру temp->Next = Head; //Указываем, что адрес следующего элемента это начало списка //Копирование содержимого параметра student в только что созданную переменную strcpy(temp->Name, student.Name); strcpy(temp->NameLast, student.NameLast); temp->Age = student.Age; strcpy(temp->School, student.School); Head = temp; //Смена адреса начала списка } /*ФУНКЦИЯ КЛАССА LIST ДЛЯ ВЫВОДА СПИСКА НА ЭКРАН*/ void List::Show() { Student *temp = Head; //Объявляем указатель и изначально он указывает на начало while (temp != NULL) //Пока по адресу на начало хоть что-то есть { //Выводим все элементы структуры cout << temp->Name << "\t\t"; //Вывод имени cout << temp->NameLast <<"\t\t"; //Вывод фамилии cout << temp->Age << "\t\t"; //Вывод возраста cout << temp->School << endl; //Вывод места учебы temp = temp->Next; //Указываем на следующий адрес из списка } cout << endl; } int main () { Student student; //Объявили переменную, тип которой Студент int N; //Объявили переменную - число студентов List lst; //Объявили переменную типа Список. Она выступает как контейнер данных cout << "N = "; cin >> N; //Ввели число студентов cin.ignore(); //Игнорируем клавишу Enter for (int i=0; i<N; i++) { student.Input(student); //Передаем в функцию заполнения переменную студент lst.Add(student); //Добавляем заполненную структуру в список } cout << endl; lst.Show(); //Показываем список на экране cin.ignore().get(); return 0; } |
======================================================================
======================================================================
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//Листинг #4a class List { Node *Head; int size; public: List():Head(NULL),size(0) {}; //Инициализация значений с помощью конструктора ~List(); void Add(const int x); //Дописано слово const void Show(); void Pop(const int N); //Объявлена функция извлечения элемента int Count() {return size;}; //Внутри класса описана функция-счетчик }; void List::Add(const int x) { size++; //При каждом вызове функции добавления увеличивается счетчик элементов |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//Листинг #4b /*ФУНКЦИЯ ИЗВЛЕЧЕНИЯ ЭЛЕМЕНТА ОПИСАНА ВНЕ КЛАССА*/ void List::Pop(const int N) //В качестве параметра принимается номер извлекаемого элемента { Node *temp = Head; //Обращаемся к началу списка if ((Head != NULL) && (N < size)) //Делаем проверку на то что список не пуст и N не превышает число его элементов { for (int i=0; i<N; i++) temp = temp->Next; //Меняем адрес N раз cout << temp-> x << " " << endl; //Выводим N элемент списка на экран } cout << endl; } |
1 2 3 4 5 6 |
//Листинг #4c lst.Pop(0); //Извлечение первого элемента lst.Pop(1); //Извлечение второго элемента lst.Pop(2); //Извлечение третьего элемента cout << lst.Count() << " " << endl; //Вызов Функции вывода числа элементов списка на экран |
Я немного усовершенствовал, и перегрузил cin>> и <<cout для отдельной структуры student чтобы можно было сделать класс list шаблонным…
Спасибо очень помогло в понимании.
все очень понятно написано…спасибо за предоставленную информацию…
такой вопрос . вот сейчас разбираюсь со списоком, и там есть такое понятие как фиктивный узел …что такое фиктивный узел и как его объявлять ? спасибо
Фиктивный узел — это узел, который указывает на пустое значение
В моем примере (в случае с LIFO)
Head = NULL, значит Head = фиктивный узел
============
Списки могут быть построены по разному, поэтому если есть не пустой узел P и P->Next=NULL, то при P=P->Next, P будет фиктивным узлом.
вот как-то так
Спасибо автору за классную информацию.
В листинге 2 есть небольшая ошибка в деструкторе,
Надо записать,
Так как Вы используете структуру element, а не Node.
Можно еще в учебных целях вставить строку в деструкторе
для проверки работы деструктора.
Спасибо автору за отличный сайт.
Благодарю за показанную ошибку. Исправлено.
Вам бы еще кнопку для отображения печатной версии статьи, и было бы просто великолепно! Статьи супер, объясняешь очнь понятным языком =))
Спасибо автору за статью, очень хорошо описано, но там в Show() в первом классе есть утечка памяти, было
правильно будет
пока не проверил, но сомневаюсь, что так правильно.
мои сомнения напрасны. Вы правы.
Мне нужно удалить первые k элементов из конца. Все описано так как у вас.
Вот мой код функции для удаления k элементов из начала :
void List::Delete(List ¤t, int k)//k-кол-во элементов которые надо удалить
{
if(k==0)
{
cout<<"Uncorrect value"<next;
delete head;
current.head=temp;
k—;
}
}
}
Скажите пожалуйся, что исправить, чтобы удалялись элементы с конца?
не то прислал. извиняюсь
void List::Delete(List ¤t, int k)
{
while(current.head!=NULL && k!=0)
{
Info *temp=current.head->next;
delete head;
current.head=temp;
}
}
Может подход исправить нужно?
Если список имеет вид: 1,2,3 , и 1 — это начало, а 3 -это конец списка, то
Для операций только к начальной части списка использовать FIFO
Для операция только к конечной части списка использовать LIFO
Для операций к обеим частям списка использовать двусвязный список
====================
Можно выпендриваться и решать задачи, используя алгоритмы не по своему назначению, а по назначениям на 100% несоответствующим идеям алгоритмов.
У меня и на простые ответы сейчас возможностей не особо, а на разный выпендреж точно нету.
хотя я может не понял.
если
1 2 3 4 5
и при удалении 3 элементов должно стать
1 2
то я сейчас посмотрю, должно быть просто
да именно так
точнее в LIFO достаточно просто удалять так
Список 1 2 3 4 5
Удалить 3 элемента
Список стал 4 5
====================
а иначе (именно чтоб по LIFO) можно,но у меня сейчас нет желания и возможности заниматься такими вещами.
я могу только подсказать. Каждый раз придется копировать весь список без последнего элемента. Путем такого копирования получится эффект удаления с обратной стороны.
Попробую, спасибо!)
Еще не забывайте удалять тот элемент, который не включается при копировании. (а-то совсем не удаление будет)
Думаю по разному можно делать и думаю я предложил не самый изящны и не самый простой.
Здравствуйте! Очень помогает эта информация. Но никак не могу понять как записать список в обратном порядке 🙁 Не могли бы Вы помочь?
в обратном порядке список FIFO называется
Дело в том, что мне нужно записать список в обратном порядке с помощью одного указателя.
Я не понимаю вопроса. 😐
Вот данные 1,2,3,4,5
Есть два варианта списка
_______________
5,4,3,2,1 (LIFO, стек)
1,2,3,4,5 (FIFO)
_______________
Чтобы делать FIFO Нужен указатель на начало и указатель на следующий элемент в списке.
Чтобы делать LIFO достатоно одного указателя на следующий элемент в списке.
(насколько я знал (вероятно ошибочно). я давно этим всем не занимаюсь)
а как вызвать в основной части деструктор, для удаления списка?
Здравствуйте,нужна помощь.
Удалить из очереди все элементы , расположенные между минимальным и максимальным элементами очереди.
Здравствуйте, пытаюсь сделать шаблонным этот стек:
однако, ошибка тут
Link<T>* newlink = new Link;
1) нет подходящего ctor’a по ум 2) для исп-я класса-шаблона требуется список аргументов. Подскажите, пожалуйста, в чем проблемаспасибо! а почему у меня не получается оформить код в комментариях правильно? Я делаю так: нажимаю на кнопку <>, выбираю язык с++, вставляю код (вроде бы видно что он выделен от остального текста в комментарии)
но когда публикую, то нет того черного фона и нумерованных строк и подсветки. Может быть нужно какую то конкретную тему выбрать?
Потому что не прочитан красно-бордовый текст, предваряющий начало комментариев, где написано большими буквами:
Для вставки кода в комментарий, вставьте ваш код в php теги:
[php
]
ВАШ КОД[
/php]Добрый день. Один вопрос интересует: если все сделать, НЕ ИСПОЛЬЗУЯ структуру. Это является правильным решением?
Расписано понятно, но мне всё равно тяжело. Постепенно понимаю, огромное спасибо за предоставленную информацию!
С помощью класса.
Смысл такой, что при «правильном решении» получается некоторого рода массив, который хранит адреса на свои элементы.
Структура и класс в c++ это одно и то же.
Можно написать один класс, это будет хорошо. У меня разделено только потому, что я плохо понимал что это вообще такое, один из наиболее понятных для себя примеров, я описал в этой теме.
Спасибо большое Вам! Делаю только класс, наловчился, удобно:)
как перегрузить оператор = для списка
1. Можно написать отдельную функцию-член класса, которая будет копировать список в список. Её переделать под оператор =.
2. Написать конструктор копирования. Это так вообще делать правильно. А в операторе перегрузки просто использовать этот конструктор.
Сможете написать конструктор копирования?
Если Вы хотите понять и разобраться, то имеет смысл его написать своими силами. Потом всё совсем просто.