Линейный двусвязный список из четырёх элементов. Обращу внимание, что указатели содержат адреса начала структуры в памяти, т.е. графически, стрелки должны указывать на начало прямоугольников. Когда рисовал схемку не придал этому большого значения, но всё-таки обращу на это внимание. (это касается стрелок обратных указателей и указателя конца списка) Начнём пожалуй. Особо код не вылизывал, да и не стремился сделать супер программу. Code #include <iostream> using namespace std;
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ typedef struct element { element* prev; char inf; element* next; } NODE;
//Поля структуры я расположил так намеренно для ясности //Определяем синоним нашей структуре, кстати размер структуры 12 байт //По сути должно быть 9, два 4-х байтных указателя и и один однобайтный символ //Машины не очень любят нечётные числа, думаю значение специально выравнено /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
//Формирование списка //Функция возвращает указатель на сформированный узел NODE* forming_list () { NODE* addElement = NULL; //NULL - это синоним 0-я (#define NULL 0) вот так это делается, а вообще это значит что элемент не имеет определённого значения NODE* tempElement; char ch; //Символ
do // делать (дословный перевод) { tempElement=new(NODE); //Выделяем память в куче под новый узел, переменная temp содержит адрес, т.к. temp - Это указатель //Ну вот, мы создали элемент списка cout << "Адресс переменной temp = " << tempElement << endl; //Куда его запихнула ОС tempElement->next=addElement; // обращаемся к полям структуры через стрелку, так как temp - указатель // указатель next теперь указывает на элемент переданный через параметр в функцию tempElement->prev=NULL; //Это первый элемент списка, поэтому слева он не ссылается на другой элемент // на предыдущий элемент не ссылаемся cout<<"Введите символ ('*'-закончить ввод):"; //выводим надпись cin>>ch; //вводим символ tempElement->inf=ch; //сохраняем символ в элементе addElement=tempElement; //теперь, начинаем плясать от temp // if(tempElement->prev!=NULL) tempElement->prev->next=tempElement; //Вот тут глвное сильно не напрягать мозги, если не понятно, будем разжёвывать
} while(ch!='*'); // (пока ввёдённый символ не окажется звёздочкой) cout << "\n Конец списка\n"; return tempElement; //Возвращаем список }
//Выводим содержимое списка с элемента inputE void out_list (NODE* inputE) { NODE* temp; temp = inputE->next; cout << "\n\n Распечатка списка:\n\n"; do { cout << "" << temp->inf; temp=temp->next; } while(temp!=NULL); }
//Добавить элемент после последнего void addElementToRigth(NODE* list, char inf) { NODE* listTemp = new NODE; //Указатель на область памяти, где хранится новый узел listTemp->inf = inf; //Заполняем узел listTemp->prev = list; //Слева у нас остаётся элемент писка в который мы делаем вставку listTemp->next = list->next; //Наш вставляемый элемент будет теперь ссылаться на элемент, на котороый ссылался элемент списка //в который мы вставляем элемент (звучит бредово, но понять можно) list->next = listTemp; //Наш элемент становится следующим элементом списка listTemp->next->prev = listTemp; }
void main(void) { setlocale (LC_ALL, "rus"); cout << "Размер структуры NODE = " << sizeof(NODE) << endl; NODE* top = forming_list(); //Формируем список используя top; //top - первый элемент, от которого мы попляшем немного cout<<"Адрес переменной top после формирования ="<<top; out_list (top); addElementToRigth(top->next, 'z'); out_list(top); //Выводим список после вставки элемента cout<<"\n\n Конец программы\n"; system ("pause"); } Программа представляет из себя смесь Си и Си++ (Си больше), вывод на консоль и ввод выполним с помощью прастранства имён std конечно же как это пологается в Си++. Функция main содержит в себе вызовы троечки интересующих нас функций для создания и использования списка. Первая (NODE* forming_list ()) функция формирует список и возвращает указатель на последний элемент списка. Функция (void out_list (NODE* inputE)) выводит список начиная с элемента inputE Функция (void addElementToRigth(NODE* list, char inf)) добавляет элемент следом за элементом list Вообще эта тема очень интересная, но если в неё очень сильно начать вникать сходу, то может получиться кашица в голове. Во-первых нужно чётко представлять себе, что данные хранятся в памяти и что указатель это переменная хранящая адрес начала участка памяти, где хранятся наши данные. Итак, наши данные. Список в нашей программе представляет собой структуру с тремя переменными, двумя указателями на эту же структуру и одним символом. Формирование списка начинается с создания в куче экземпляра нашей структуры и установкой его указателей на самого себя (изначально указатели указывают на NULL) Единственный элемент созданный в списке ссылается на себя. В этой программе имеется недоработка, при добавлении элемента к списку из одного элемента повергнет программу в дикий ужас с ошибкой доступа к памяти. (Ну это уже вам дорабатывать если понадобится) Вывод элементов списка на экран, а точнее символа в элементе происходит перебором адресов хранящихся в указателях. Добавление элемента совершается довольно элементарно, создаётся экземпляр структуры и путём манипуляции с указателями элемент магическим образом оказывается вставленным в список. В этой программе элемент добавляется после первого элемента, так как в параметр функции добавляющую новый элемент мы засылаем адрес (указатель ) первого элемента. После формирования списка в переменной top оказывается адрес первого элемента. При выводе списка на экран мы используем эту-же переменную. Ну вот в вкратце вроде бы и всё. В коде есть комментарии, возможно не особо отражающие суть, но нужные. Хотел эту статью изначально расписать во всех красках, со скриншотами точек останова и содержимым переменных, но, к сожалению осознал, что это займёт много времени, которого у меня не хватает. Поэтому, желаю удачи. Кстати первым элементом становится последний символ который вы введёте, изучите это. Ну и воспользуйтесь отладкой, точками останова для более детального понимания. Будет время, попробую довести до ума статью.
|