Министерство образования и науки РФ Федеральное государственное бюджетное образовательное учреждение высшего профессионального образования Самарский государственный архитектурно-строительный университет Факультет информационных систем и технологий Кафедра прикладной математики и вычислительной техники О. В. ПРОХОРОВА МЕТОДИЧЕСКИЕ УКАЗАНИЯ для выполнения лабораторных работт по дисциплине “Технология программирования” Самара 2012г. Оглавление Постановка задачи проектирования .......................................................................... 3 Аналитическая часть ................................................................................................... 3 Листинг программы .................................................. Error! Bookmark not defined. Результаты тестирования ......................................................................................... 15 Литература ................................................................................................................. 16 Постановка задачи проектирования В ходе выполнения лабораторной работы студент должен самостоятельно изучить теорию, в рамках которой поставлена тема курсовой работы, разработать алгоритм решения задачи, написать программу на языке С++, протестировать разработанную программу. В качестве примера будет рассматриваться тема «Разработать код программы работы со списком данных с динамическим выделением памяти». 1. Аналитическая часть Рассмотрим принципы организации работы с данными при связанном распределении данных. При связанном распределении данных каждому Si поставлен в соответствие указатель Рi, отмечающий ячейку, в которой записаны Si+1 и Pi+1 (т.е. переход на следующую ячейку последовательности). Существует также указатель P0, который указывает на начальную ячейку последовательности, т.е. на ячейку с содержимым S1 и P1. (INFO) (LINK) P0=l1 S1 l1 P1=l2 S2 P2=l3 … l2 Sn-1 l n-1 Pn-1=ln Sn Pn= ln Рис. 1. Представление последовательности в виде связанного списка Каждый элемент списка состоит из поля INFO (содержащего элемент последовательности) и поля LINK (содержащего адрес следующего элемента) 3 Здесь каждый узел состоит из двух полей. Под узлом понимается одно или несколько последовательных слов в памяти машины, выступающих как единое целое. — пустой или нулевой указатель. Рассмотрим более употребляемый способ задания списка. P0 S1 S2 … Sn-1 Sn Рис. 2. Способ задания списка Связанное представление данных облегчает операции включения и исключения элемента, если ячейка Si известна. Для этого лишь необходимо, изменить значение некоторых указателей. Например, чтобы исключить элемент S2 из последовательности, изображенной на рис. 2.2, необходимо положить LINK(l1)=LINK(l2). После этой операции элемента S2 в последовательности больше не будет. P0 S1 S2 S3 … Рис. 3. Исключение элемента из связанного списка Чтобы в последовательность (рис. 2.2) включить новый элемент S5 после S1, необходимо воспроизвести новый элемент в некоторой ячейке l5 с INFO(l5) = S5 и LINK(l5) = LINK(l1) и присвоить LINK(l1) l5. 4 P0 S1 S2 S3 … S5 l5 Рис. 4. Включение элемента в связанный список Также легко осуществляется сцепление последовательностей и разбиение последовательности на части. Использование связанного распределения предполагает существование некоторого механизма, который по мере надобности собирает ячейки (мусор), когда они освобождаются. С помощью связанного распределения достигается большая гибкость, но идет потеря скорости обращения к данным. Связанное распределение предпочтительнее, если в значительной степени используются операции включения и/или исключения элементов, а также сцепления и/или разбиения последовательностей. Разновидности связанных списков Если Pn указывает на S1, то такая форма списка дает возможность достигнуть любой элемент списка (хотя и не прямо) из любого другого элемента последовательности. 5 P0 S1 … S2 Sn-1 Sn Рис. 5. Циклический список Включение и исключение элементов здесь осуществляется так же, как и в нециклических списках, в то время как сцепление и разбиение реализуется более сложно. Большая гибкость при работе со списками достигается, если использовать дважды связанный список, когда каждый элемент Si последовательности вместо одного имеет 2 связанных с ним указателя, они указывают на элементы Si-1 и Si+1. В таком списке для любого элемента имеется мгновенный прямой доступ к предыдущему и последующему элементам, в связи с чем облегчаются такие операции, как включение нового элемента перед Si и исключение Si без предварительного знания его предшественника. Если есть необходимость, дважды связанный список можно сделать циклическим. P0 S1 S2 … Рис. 6. Дважды связанный список 6 Sn-1 Sn 2. Алгоритмическая часть Построение объекта список с динамическим распределением памяти предполагает создание двух типов объектов: самого списка и его элементов, т.к. в последнем предполагается увязка элементов списка через указатели. Алгоритм создания списка и работы с ним таков: 1. Создание класса item. 3. Конструкторская часть #include "stdafx.h" #include <iostream> using namespace std; #include <conio.h> /*** * * КЛАСС: item * * НАЗНАЧЕНИЕ: Контейнер для элементов структуры * ****/ class item { char info; // информация в узле(ячейке) item *next; // ссылка на следующий узел(ячейку) public: item(char,item *); // конструктор ~item(); // дестуктор char get_info(); // функция возврата информационной части элемента (узла) 7 item* get_next(); // функция возврата указателя на следующий элемент (узел) void set_info(char); // функция вставки в список информационной части элемента void set_next(item*); // функция вставки в элемент указателя на следующий элемент }; item::item(char ch,item *l) { info = ch; next = l; // указатель на следующий элемент списка } item::~item() { } char item::get_info() { return info; } item* item::get_next() { return next; } void item::set_info(char ch) { info=ch; } void item::set_next(item* next_next) { next=next_next; } 8 /*** * * КЛАСС: list * * НАЗНАЧЕНИЕ: Организация структуры типа список * ****/ class list { int number; //число элементов в списке public: list(); // конструктор списка ~list(); // дестуктор списка item * push(item *tt,char ch,int k); // вставка в список void pop(item *tt,item *next_next); // удаление из списка item * search(item *tt,char ch,int n); // просмотр списка void set_number(); // подсчет числа элементов списка int get_number(); // вывод числа элементов списка item * set_tt(char ch); // формирование начала списка и вывод его указателя }; list::list() { number=0; } list::~list() { } // подсчет числа элементов списка void list:: set_number() { number++; 9 } // вывод числа элементов списка int list:: get_number() { return number; } // формирование начала списка и вывод его указателя item * list::set_tt(char ch) { item *tt; item *temp; item *l; l=NULL; temp = new item(ch,l); //Создается объект item tt=temp; tt->set_info(ch); tt->set_next(l); return tt; } // вставка элемента в список item * list::push(item *tt,char ch,int kk) { int i; item *t; item *l; l=NULL; t=tt; item *temp = new item(ch,l); // создается объект item // поиск места вставки в список и смена указателей 10 if(kk==0) // вставка в начало списка, если список не пуст { temp->set_info(ch); temp->set_next(tt); tt=temp; //** return tt; } else { for(i=1;i<=kk;i++) // проход с начала списка { l=t; t=t->get_next(); } temp->set_info(ch); temp->set_next(t); l->set_next(temp); return t; } } // УДАЛЕНИЕ элемента из списка void list::pop(item *tt,item *next_next) // next_next - адрес элемента, ссылающегося на удаляемый { char ch; item* temp; item *l; if (tt == NULL) { 11 cout << "list is empty "; return; } temp=next_next->get_next(); // адрес удаляемого элемента ch=temp->get_info(); l=temp->get_next(); next_next->set_next(l); delete temp; } // ПОИСК элемента в списке item * list::search(item *tt,char ch,int nn) // возврат указателя на элемент, ссылающийся на искомый { int i=1; item *temp=tt; item *t=NULL; item *h; while(i<=nn) { if(temp->get_info()==ch) { cout<<"element exists\n"; h=t; return h; } t=temp; temp=t->get_next(); i++; } cout<<"Element does not exist\n"; h=NULL; 12 return h; } int main() { list *s= new list; // создание объекта - список int i,n,nn; char ch; item *tt; // указатель на вершину списка item *h; item *l; h=NULL; tt=NULL; cout<< "Enter size of list\n"; cin>>n; cout<<" Enter items of list\n"; for(i=1;i<=n;i++) { cin>>ch; s->set_number(); nn=s->get_number(); if(i==1) tt=s->set_tt(ch); else s->push(tt,ch,i-1); } cout<<"Do you like search item?\n"; cin>>ch; if((ch=='Y')||(ch=='y')) { cout<<"Enter item for search\n"; cin>>ch; 13 h=s->search(tt,ch,nn); cout<<"Enter 'Y' you like to delette item\n"; cin>>ch; if((ch=='Y')||(ch=='y')) { if(h==NULL) tt=tt->get_next();// удаляется 1-й элемент else s->pop(tt,h); nn=nn-1; } } else { cout<<"Do you like add item?\n"; cin>>ch; if((ch=='Y')||(ch=='y')) { cout<<"Enter add item's information \n"; cin>>ch; cout<<"Enter number item after that it should be add\n"; cin>>i; if(i==0) tt=s->push(tt,ch,i); s->push(tt,ch,i); s->set_number(); nn=s->get_number(); } } // печать списка h=tt; for(i=1;i<=nn;i++) { 14 l=h;h=h->get_next(); ch=l->get_info(); cout<<"\n"<<ch; } delete s; // удаление объекта список return 0; } 4. Результаты тестирования ВАРИАНТЫ тестов 1 2 3 4 5 Enter size of list Enter size of list Enter size of list Enter size of list Enter size of list 6 4 3 3 3 Enter items of Enter items of Enter items of Enter items of Enter items of list list list list list 15 1 A A 1 1 2 S B 2 2 3 D C 3 3 4 F 5 6 Do you like Do you like Do you like Do you like Do you like search item? search item? search item? search item? search item? y y y n n Enter item for Enter item for Enter item for Do you like add Do you like add search search search item? item? 4 D f y y Element exists Element exists Element does not Enter new item Enter new item 4 4 Enter item’s Enter item’s number after that number after that it should be add it should be add 3 0 1 4 2 1 3 2 4 3 exists Enter ‘Y’ if you Enter ‘Y’ if you Enter ‘Y’ if you like to delete like to delete like to delete item item item y y n 1 A A 2 S B 3 F C 5 6 Литература 16 1. Ленгсам Й., Огенстайн М., Тененбаум. Структуры данных для персональных ЭВМ. — М.: Мир, 1989. — 568 с. 2. Павловская Т.А. С/С++. Программирование на языке высокого уровня. СПб.: Питер. 2004. 3. Прохорова О.В. Методы программирования : учебное пособие: курс лекций для студентов специальности 090102 «Компьютерная безопасность». Йошкар – Ола: МФ МОСУ, 2007. – 178с. 17