Создание библиотеки контейнерных классов для реализации динамической структуры списка
Определение понятия связного списка. Организация односвязного, двусвязного, односвязного циклического и двусвязного циклического списков. Описание логической структуры списков, особенности их элементов. Особенности продвижения данных в разных списках.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | курсовая работа |
Язык | русский |
Дата добавления | 16.09.2017 |
Размер файла | 368,4 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Министерство образования и науки Российской Федерации
Федеральное государственное бюджетное образовательное учреждение высшего профессионального образования
«Магнитогорский государственный технический университет
им. Г.И. Носова»
Кафедра вычислительной техники и прикладной математики
Курсовая работа
по дисциплине «Структуры и модели данных»
на тему: «Создание библиотеки контейнерных классов для реализации динамической структуры списка»
Исполнитель: Молдачев С.О. студент гр. АВБ-11-1
Проверил: Торчинский В.Е.
Магнитогорск, 2013
Содержание
- Введение
- 1. Теоретическая часть
- 1.1 Односвязный и односвязный циклический списки
- 1.2 Двусвязный и двусвязный циклический списки
- 2. Практическая часть
- 2.1 Листинг заголовочного файла «List.h»
- 2.2 Листинг файла «List.cpp»
- Заключение
- Список использованных источников и литературы
- Приложение
Введение
C++ -- компилируемый язык программирования общего назначения, сочетает свойства как высокоуровневых, так и низкоуровневых языков программирования. В сравнении с его предшественником -- языком программирования C, -- наибольшее внимание уделено поддержке объектно-ориентированного и обобщённого программирования. Название «язык программирования C++» происходит от языка программирования C, в котором унарный оператор ++ обозначает инкремент переменной.
Не существует единственного самого лучшего способа создания программ. Для решения задач разного рода и уровня сложности требуется применять разные технологии программирования. Довольно часто можно встретить задачи, в которых количество элементов постоянно меняется, но при этом последовательность следования объектов должна оставаться неизменной. Но более жестким условием является непредсказуемость количества «объектов». В подобных случаях можно заказать массив размером, превышающий максимально возможный. Однако это неэффективно и могут возникнуть проблемы в других частях программы. Лучшим решением является организация списков.
Организация односвязного, двусвязного, односвязного циклического и двусвязного циклического списков и является целью моей работы.
1. Теоретическая часть
1.1 Односвязный и односвязный циклический списки
Связный список - структура, элементы которой имеют один и тот же формат и связаны друг с другом с помощью указателей, хранящихся в самих элементах.
В односвязном списке каждый элемент состоит из двух различных по назначению полей: содержательного поля (поле данных) и служебного поля (поля указателя), где хранится адрес следующего элемента списка (рис.1). Поле указателя последнего элемента списка содержит нулевой указатель, свидетельствующий о конце списка.
Рис.1. Односвязный список. Логическая структура.
Линейность односвязного списка вытекает из линейной логической упорядоченности его элементов: для каждого элемента, за исключением первого и последнего, имеются единственный предыдущий и единственный последующий элементы. Односвязные списки всегда линейны, поэтому особое внимание следует уделить проблеме перестройки списка при его повреждении.
Логическая структура линейного односвязного списка:
Имя списка (идентификатор), тип элементов списка, указатель начала списка, указатель текущего элемента списка.
Логическая структура элемента линейного односвязного списка:
Данные или указатель на данные, указатель на следующий элемент списка.
Продвижение в линейном односвязном списке возможно только в одном направлении. Результаты выполнения операций включения элемента в линейный односвязный список и исключения элемента из линейного односвязного списка - линейный односвязный список.
связный список циклический логический
Рис.2. Выполнение операции включения элемента в линейный односвязный список.
Рис.3. Выполнение операции исключения элемента из линейного односвязного списка.
Для ускорения операции доступа к элементам односвязного списка поле указателя последнего элемента односвязного списка содержит указатель на начало списка. Такая разновидность линейного односвязного списка называется кольцевой односвязный список (рис.4), причем первым элементом такого списка может быть любой из его элементов.
Рис.4. Кольцевой односвязный список. Логическая структура.
1.2 Двусвязный и двусвязный циклический списки
В линейном двусвязном списке продвижение возможно в любом из двух направлений по цепочке элементов. Каждый элемент двусвязного списка содержит два указателя: указатель на следующий элемент, или прямой указатель, и указатель на предыдущий элемент, или обратный указатель (рис.5). У первого элемента двусвязного списка обратный указатель пустой, а у последнего элемента двусвязного списка - прямой указатель.
Рис.5. Линейный двусвязный список. Логическая структура.
Линейность такого списка обеспечивается тем, что каждый из двух указателей в любом элементе списка, кроме крайних, задает линейный порядок элементов, обратный по отношению к порядку, устанавливаемому другим указателем (рис.6).
Рис.6. Линейность двусвязного списка.
Логическая структура линейного двусвязного списка:
Имя списка (идентификатор), тип элементов списка, указатель начала списка, указатель конца списка, указатель текущего элемента списка.
Логическая структура элемента линейного двусвязного списка:
Данные или указатель на данные, указатель на следующий элемент списка, указатель на предыдущий элемент списка.
Продвижение в линейном двусвязном списке возможно в любом направлении. Операции включения элемента в линейный двусвязный список и исключения элемента из линейного двусвязного списка реализуются аналогично соответствующим операциям над линейным односвязным списком. Результат выполнения операций включения элемента в линейный двусвязный список и исключения элемента из линейного двусвязного списка - линейный двусвязный список.
Для получения из линейного двусвязного списка кольцевого двусвязного списка необходимо два пустых указателя заменить указателями противоположных концов списка (рис.8).
Рис.8. Кольцевой двусвязный список. Логическая структура.
2. Практическая часть
2.1 Листинг заголовочного файла «List.h»
#ifndef LIST
#define LIST
#include <iostream.h>
template <class T> class List
{
struct Element {
T data;
Element *next; // указатель на следующий элемент списка
};
private:
Element *pHead; // указатель на первый элемент списка
Element *pPrev; // указатель на последний элемент списка
int countElem; // количество элементов в списке
public:
List()
{
pHead = 0;
pPrev = 0;
countElem = 0;
}
~List()
{
delAllList();
}
void add_front(T data)
{
Element *temp = new Element;
temp->next = pHead;
pHead = temp;
if(pPrev == 0){
pPrev = pHead;
}
pHead->data = data;
countElem++;
}
void add_back(T data)
{
Element *temp = new Element;
if(pHead == 0){
pHead = temp;
}
else{
pPrev->next = temp;
}
temp->data = data;
temp->next = NULL;
pPrev = temp;
countElem++;
}
friend ostream &operator << (ostream &print,List<T> &k)
{
Element *pTemp;
pTemp=k.pHead;
print<<"(";
while(pTemp != 0)
{
print << pTemp->data <<" ";
pTemp = pTemp->next;
}
print<<")"<<endl;
}
void delAllList()
{
while(pHead != NULL)
{
Element *pTemp = pHead;
pHead = pHead->next;
delete pTemp;
}
countElem=0;
}
bool IsEmpty()
{
if(countElem == 0){
return true;
}
else{
return false;
}
}
bool erase(T val)
{
Element* ptrPrev;
int i=0;
ptrPrev=new Element;
for(Element* ptr=pHead; ptr!=0; ptr=ptr->next)
{
if(ptr->data==val){
ptrPrev->next=ptr->next;
delete ptr;
countElem--;
i++;
break;
}
ptrPrev=ptr;
}
if(i==0)
return false;
else
return true;
};
bool find(T val)
{
for(Element* ptr=pHead; ptr!=0; ptr=ptr->next)
{
if(ptr->data=val)
return true;
}
return false;
}
};
//---------------------------------------------------------------------------
template <class T> class DoubleList
{
struct Elem{
T data;
Elem * next, * prev;
};
Elem* Head; // Голова
Elem* Tail; // Хвост
int Count;
public:
DoubleList()
{
Head = Tail = NULL;
Count = 0;
}
~DoubleList()
{
DelAll();
}
int GetCount()
{
return Count;
}
void DelAll()// Удалить весь список
{
while(Count != 0)
{
Del(1);
}
}
void Del(int pos) // Удаление элемента
{
int i = 1;
Elem * Del = Head;
while(i < pos)
{
Del = Del->next; // Доходим до элемента, который удаляется
i++;
}
Elem * PrevDel = Del->prev; // Доходим до элемента, который // предшествует удаляемому
Elem * AfterDel = Del->next; // Доходим до элемента, который // следует за удаляемым
if(PrevDel != 0 && Count != 1){ // Если удаляем не голову
PrevDel->next = AfterDel;
}
if(AfterDel != 0 && Count != 1){ // Если удаляем не хвост
AfterDel->prev = PrevDel;
}
if(pos == 1){ // Удаляются крайние?
Head = AfterDel;
}
if(pos == Count){
Tail = PrevDel;
delete Del; // Удаление элемента
Count--;
}
void Insert(int pos, T inf) // Вставка элемента,
{
if(pos == Count + 1) // Если вставка в конец списка
{
AddTail(inf);
}
else if(pos == 1){
AddHead(inf);
}
int i = 1;
Elem * Ins = Head; // Отсчитываем от головы n - 1 элементов
while(i < pos)
{
Ins = Ins->next; // Доходим до элемента, перед
// которым вставляемся
i++;
}
Elem * PrevIns = Ins->prev; // Доходим до элемента,
// который предшествует
Elem * temp = new Elem;
temp->data=inf;
if(PrevIns != 0 && Count != 1){// настройка связей
PrevIns->next = temp;
temp->next = Ins;
temp->prev = PrevIns;
Ins->prev = temp;
Count++;
}
void AddTail(T n) // Добавление в конец списка
{
Elem * temp = new Elem;
temp->next = 0; // Следующего нет
temp->data = n;
temp->prev = Tail; // Предыдущий - бывший хвост
if(Tail != 0){ // Если элементы есть
Tail->next = temp;
}
if(Count == 0){ // Если элемент первый, то
// он одновременно и голова и хвост
Head = Tail = temp;
}
else{
Tail = temp; // иначе новый элемент - хвостовой
}
Count++;
}
void AddHead(T n) // Добавление в начало списка
{
Elem * temp = new Elem;
temp->prev = 0; // Предыдущего нет
temp->data = n;
temp->next = Head; // Следующий - бывшая голова
if(Head != 0){ // Если элементы есть
Head->prev = temp;
}
if(Count == 0){ // Если элемент первый, то он одновременно
// и голова и хвост
Head = Tail = temp;
}
else{
Head = temp; // иначе новый элемент - головной
}
Count++;
}
friend ostream &operator << (ostream &print,DoubleList<T> &k)
{
Elem * temp;
temp=k.Head;
print << "( ";
while(temp->next != 0)
{
print << temp->data << ", ";
temp = temp->next;
}
print << temp->data << " )\n";
}
};
//---------------------------------------------------------------------------
template <class T> class CycleDoubleList
{
struct Element
{
T data;
Element *next;
Element *prev;
};
private:
Element *Head;
Element *Curr;
int length;
public:
CycleDoubleList()
{
Head =NULL;
Curr=NULL;
length=0;
}
~CycleDoubleList()
{
clear();
}
void init()// приведения списка к состоянию текущий
{ // элемент - первый не удаленный
Curr=Head; // устанавливаем текущий элемент на первый не удаленный
}
void push(T data) // добавляем новый элемент в список
{
Element *inserted;
inserted= new Element;
inserted->data=data;
if (!isNoEmpty()) // если список пуст
{
Head=inserted;
Curr=inserted;
Curr->next=inserted;
Curr->prev=inserted;
}
else // если список не пуст
{
inserted->next=Curr->next;
inserted->next->prev=inserted;
Curr->next=inserted
inserted->prev=Curr
}
length++;
Curr=inserted; // устанавливаем текущий указатель на добавленный
}
T pop()// извлекаем текущий элемент
{
T tag; // переменная под возвращаемое значение
if (!isNoEmpty()) return 0; // если список пуст вернуть "ложь"
Element *temp=Curr; // сохраняем указатель на текущий элемент
tag=temp->data;
if (length==1){ // если элемент единственный в списке
Head=NULL; // обнулить значение первого элемента
Curr=NULL; // обнулить значение текущего элемента
}
else{
Curr->next->prev=Curr->prev;
Curr->prev->next=Curr->next;
Curr=Curr->next;
}
if(temp==Head){ // если удаляемый элемент - первый добавленный
Head=Head->next; // перенаправить первый на следующий
}
length--;
delete temp;
return tag;
}
void delFromData(T adr) // находим и удаляем элемент
{ // содержащий переданные данные
if(isNoEmpty())
{
Element *tmp=Curr;
for(int i=0;i<length;i)
{
if(Curr->data==adr)
{
if(Curr==tmp){
tmp=tmp->next
pop(); // извлечь значение
}
next(); // перейти к следующему элементу
}
Curr=tmp;
}
}
}
friend ostream &operator << (ostream &print,CycleDoubleList<T> &k)
{
Element *tempCar;
tempCar=k.Head;
print<<"(";
for (int i=0;i<k.length;i++)
{
print <<tempCar->data <<" ";
tempCar=tempCar->next ;
}
print << ")"<<endl;
}
void clear()// очистить весь список
{
for(int i=0;i<length;){
pop(); // извлекаем текущий элемент
}
}
void next() // перейти к следующему элементу
{
if(isNoEmpty()){
Curr=Curr->next;
}
}
void prev() // перейти к предыдущему элементу
{
if(isNoEmpty()){
Curr=Curr->prev;
}
}
bool isNoEmpty()// проверка состояния списка (если список не пуст)
{
if (Curr==NULL ){
return 0;
}
else{
return 1;
}
}
};
//---------------------------------------------------------------------------
template <class T> class CycleList
{
struct nodes{
T data;
nodes* next;
};
private:
nodes* head; //начало списка.
nodes* position; //активная (текущая) запись.
int count;
public:
CycleList()
{
head = NULL;
count = 0;
go_first();
}
~CycleList()
{
free();
}
void insert(T data) //Вставляет запись за текущей.
{
nodes* new_node = new nodes;
new_node->data = data;
if(position != NULL){
new_node->next = position->next;
position->next = new_node;
}
else{
new_node->next = new_node;
position = head = new_node;
}
count++;
}
void del_next()//Удаляет запись за текущей.
{
if (position != NULL){
nodes* tmp = position->next;
position->next = position->next->next;
if(tmp == head) head = tmp->next;
delete tmp;
}
count--;
}
void go_next()//Переходит к следующей записи.
{
if (position != NULL)
position = position->next;
}
void go_first()//Переходит к первой записи.
{
position = head;
}
int size()//Возвращает количество элементов в списке.
{
return count;
}
void free()//удаляет все элементы, освобождает память
{
go_first();
while(head->next != head) del_next();
del_next();
}
bool isNoEmpty()
{
if (count==0)
return false;
else
return true;
}
friend ostream &operator << (ostream &print,CycleList<T> &k)
{
nodes *temp;
temp=k.head->next;
print<<"(";
for (int i=0;i<k.count;i++)
{
print <<temp->data <<" ";
temp=temp->next ;
}
print << ")"<<endl;
}
};
#endif
2.2 Листинг файла «List.cpp»
//---------------------------------------------------------------------------
#pragma hdrstop
#include "List.h"
#include <stdio.h>
//---------------------------------------------------------------------------
#pragma argsused
int main(int argc, char* argv[])
{
List <int> list;
int i;
const int n = 10;
int a[n] = {0,1,2,3,4,5,6,7,8,9};
printf("Class List: \n" );
for(i = 0; i < n; i++){
if(i % 2 == 0)
list.add_front(a[i]);
else
list.add_back(a[i]);
}
cout << list;
list.erase(5);
cout << list;
list.find(7);
printf("\n \n");
//---------------------------------------------------------------------------
DoubleList<int> L;
for(i = 0; i < n; i++){// Добавляем элементы, стоящие на четных индексах,
//в голову, на нечетных - в хвост
if(i % 2 == 0)
L.AddHead(a[i]);
else
L.AddTail(a[i]);
}
printf("Class DoubleList: \n \n");
cout << L;
L.Insert(5,3);
cout << L;
printf("\n \n");
//---------------------------------------------------------------------------
CycleDoubleList<int> M;
for(i = 0; i < n; i++)
M.push(a[i]);
printf("Class CycleDoubleList: \n");
cout<<M;
M.pop();
cout<<M;
printf("\n");
//---------------------------------------------------------------------------
CycleList<int> Cl;
for(i = 0; i < n; i++)
Cl.insert(a[i]);
printf("Class CycleList: \n \n");
cout<<Cl;
Cl.go_first();
Cl.del_next();
cout<<Cl;
getchar(); getchar();
return 0;
}
//---------------------------------------------------------------------------
Заключение
В данной курсовой работе были реализованы 4 вида списков. При изучении данной темы были полученные обширные теоретические и практические знания на тему динамических структур данных.
Список использованных источников и литературы
1. [Электронный ресурс] URL: http://algmet.narod.ru/theory_a4m/spiski/ (дата обращения 12.05.2013).
2. C/C++. Программирование на языке высокого уровня. Т.Ф. Павловская. -СПб.: Питер, 2003.- 114-119стр.
Приложение
Пример работы программы:
Размещено на Allbest.ru
...Подобные документы
Понимание принципа работы очереди. Возможности обращения к первому и последнему элементов очереди. Создание очереди с помощью массива. Рассмотрение примеров использования очереди с приоритетом в программе. Формирование односвязного и двусвязного списков.
контрольная работа [345,6 K], добавлен 26.11.2020Требование к структуре данных в базе, описание ее вида, содержание объектов. Используемые форматы данных. Алгоритмы и их особенности. Функциональное описание разработки. Описание пользовательского интерфейса. Контрольные примеры, временные характеристики.
курсовая работа [1,5 M], добавлен 06.04.2016Расположение элементов списка в памяти. Информация о полях структуры TMember. Логическая структура двусвязного кольцевого списка. Логические схемы наиболее важных операций со списками. Алгоритмы обработки основных структур. Руководство пользователя.
курсовая работа [2,3 M], добавлен 27.08.2012Понятия и методика создания списков и баз данных в Microsoft Excel. Фильтрация списков, виды сортировки данных и структурирования листа. Сортировка с помощью списка автозаполнения и "слева направо". Создание сводки о реализации товара за один день.
курсовая работа [618,3 K], добавлен 25.04.2013Понятие и обработка списков. Имя домена списка. Примеры записи списков. Основные принципы работы со списками. Рекурсивная программа обработки списка. Определение номера элемента или элемента по номеру. Решение задач, использующих структуру графа.
презентация [65,0 K], добавлен 29.07.2012Средства создания динамических структур данных. Формат описания ссылочного типа. Структура памяти во время выполнения программы. Линейные списки, стек, очередь. Организация списков в динамической памяти. Пример создания списка в обратном порядке.
лабораторная работа [788,2 K], добавлен 14.06.2009Создание баз хозяйственных договоров, банков и членов временных трудовых коллективов в среде разработки Delphi. Логическая структура линейного двусвязного списка. Способ упорядочения и алгоритм сортировки списка. Руководство пользования программой.
курсовая работа [749,4 K], добавлен 14.02.2016Написание программы, исходя из конкретных данных. Создание двунаправленного линейного списка. Main - главная программа, содержащая меню. Занесение данных в память списка. Результирующий файл. Значения всех числовых данных из диапазона целого типа данных.
курсовая работа [2,3 M], добавлен 22.12.2010Простые структуры для работы с пользователями и студентами. Описание пользовательских функций приложения. Алгоритм добавления информации о студентах в начало двусвязного списка. Удаление и фильтрация информации. Функция void menu-user. Листинг кода.
курсовая работа [1,7 M], добавлен 16.12.2014Описание процедуры выбора структуры хранения данных. Программная реализация одномерного неоднородного массива. Представление бинарного дерева в виде динамической структуры данных. Изучение способов поиска в упорядоченном дереве. Содержание базы данных.
практическая работа [850,0 K], добавлен 16.04.2015Составление алгоритма сортировки линейной вставкой. Понятие однонаправленного циклического списка символов, реализация процедуры подсчета суммы элементов и составление алгоритма. Прямое представление дерева, алгоритм работы с ним на абстрактном уровне.
контрольная работа [32,8 K], добавлен 20.01.2012Стандартные функции для работы с динамической памятью. Представление списков цепочками звеньев. Организация файлового каталога в файловой системе в виде линейного списка на языке Visual C++. Создание блок-схемы и инструкции по работе с программой.
курсовая работа [252,0 K], добавлен 22.01.2015Определение назначения и описание функций дискового кэша как промежуточного буфера с быстрым доступом к информации. Процесс кэширования внешних накопителей. Построение алгоритма, описание интерфейса и разработка программы для работы с двусвязным списком.
курсовая работа [2,1 M], добавлен 21.01.2014Средства выделения и освобождения памяти. Динамические структуры данных. Связные линейные списки и их машинное представление. Структура одно- и двухсвязного списка. Реализация операций над связными линейными списками. Разработка программы на языке С++.
курсовая работа [944,7 K], добавлен 14.03.2015Изображения древовидной структуры. Десятичная система обозначений Дьюи. Стандартные формы представления деревьев. Представление деревьев с использованием списков, с использованием списков сыновей. Полное бинарное дерево. Основные операции над кучей.
презентация [495,0 K], добавлен 19.01.2014Осуществление идентификации элемента внутри массива с помощью индекса (ключа). Понятие и свойства массивов, механизм их инициализации и создания. Недостатки непрерывных списков. Структура связного списка, удаление записи из него и добавление нового имени.
презентация [868,4 K], добавлен 14.10.2013Операции, осуществляемые с однонаправленными списками. Порядок создания однонаправленного списка, вставка и удаление элементов. Алгоритмы основных операций с двунаправленными списками. Примеры реализации однонаправленных и двунаправленных списков.
курсовая работа [172,7 K], добавлен 20.01.2016Электронные таблицы как средство формирования табличных баз данных. Структура и формирование списка при помощи формы. Сопоставление наиболее популярных систем управления базами данных. Автоматическое изменение цвета ячейки, основываясь на её значении.
курсовая работа [2,4 M], добавлен 10.01.2017Теоретическое описание линейного списка с алгоритмами реализации основных операций. Понятия, механизмы объектно-ориентированного программирования. Возможности проектируемого контейнера пользователей, его реализация на основе линейного списка с заголовком.
курсовая работа [475,2 K], добавлен 26.02.2015Состав пакета MS Office и создание списков. Оформление маркированных и многоуровневых списков. Создание баз данных в Microsoft Exсel и Access, межтабличных связей для автоматического формирования ведомости остатков вкладов с начисленными процентами.
курсовая работа [323,9 K], добавлен 25.04.2013