Главная страница
Навигация по странице:

  • Структурное описание Структура данных Двусвязный список (нециклический)

  • Функциональное описание

  • Описание пользовательского интерфейса Приложение создано в виде консоли, пользовательский интерфейс представлен в виде меню с основными операциямиВыбор типа данных

  • Вывод: Пользователь может вывести на экран объекты списка.Вставка в начало

  • Вставка в заданную позицию: При выборе этого пункта происходит вставка в заданную позицию в списке. Отсчет идет с 0-позиции.Вставка в конец

  • Сортировка: Происходит сортировка по возрастанию чисел, либо по первым буквам в типах данных char* и Class.Удаление по индексу

  • Описание работы программы

  • Программирование. Курсовая работа.. Курсовая работа. Новосибирский государственный технический универстиет министерство образования и науки российской федерации новосибирский государственный технический универстиет


    Скачать 0.8 Mb.
    НазваниеНовосибирский государственный технический универстиет министерство образования и науки российской федерации новосибирский государственный технический универстиет
    АнкорПрограммирование. Курсовая работа
    Дата04.12.2022
    Размер0.8 Mb.
    Формат файлаdocx
    Имя файлаКурсовая работа.docx
    ТипПрограмма
    #827413


    МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ

    НОВОСИБИРСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСТИЕТ

    МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ

    НОВОСИБИРСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСТИЕТ

    Пояснительная записка к курсовой работе по программированию

    «Шаблон иерархической структуры данных»

    Вариант 3.9

    Факультет: АВТ

    Группа: АВТ-710

    Студент: Покалюк Е.А.

    Преподаватель: Новицкая Ю.В.

    НОВОСИБИРСК 2018

    Оглавление


    Задание 3

    1.1. Структура данных 5

    1.2. Структурное описание разработки 5

    1.3. Вставка объекта в список 6

    1.4. Удаление объекта 6

    2.Функциональное описание 7

    2.1. List (Шаблонный класс) 7

    2.2. Node (структура собственной разработки) 8

    3.Описание пользовательского интерфейса 10

    4.Описание работы программы 10

    4.1. Примеры работы программы 10

    4.2. Тестирование на время выполнения 12

    Заключение 14

    Список используемой литературы 14

    Приложение 15


    Задание


    Для заданной двухуровневой структуры данных, содержащей указатели на объекты (или сами объекты) - параметры шаблона, разработать полный набор операций (добавление, включение и извлечение по логическому номеру, сортировка, включение с сохранением порядка, загрузка и сохранение строк в бинарном файле, балансировка – выравнивание размерностей структур данных нижнего уровня). Предполагается, что операции сравнения хранимых объектов переопределены стандартным образом (в виде операций <,> и т.д.). Программа должна использовать шаблонный класс с объектами- строками и реализовывать указанные выше действия над текстом любого объема, загружаемого из файла.

    Программа должна реализовывать указанные выше действия. Протестировать структуру данных. Программа тестирования должна содержать меню, обеспечивающее выбор операций.
    Вариант № 3.9

    Шаблон структуры данных – двусвязный список (нециклический), каждый элемент списка содержит указатель на объект. Для ускорения процедуры обхода структуры данные имеется динамический массив указателей на каждый 10-ый элемент списка (0,10,20 и т.д.).

    Структурное описание


      1. Структура данных


    Двусвязный список (нециклический) – это структура данных, состоящая из элементов одного типа, связанных между собой последовательно посредством указателей. Каждый элемент списка имеет указатель на следующий и предыдущий элементы. Элемент, на который нет указателя, является первым (головным) элементом списка. Последним элементом списка является элемент, у которого нет указателя на следующий элемент. Здесь ссылка в каждом узле указывает на следующий и предыдущий узел в списке.



    Рис 1.1 Двусвязный список



      1. Структурное описание разработки







    struct Node




    T *data;










    Node*next;




    Node*prev;




    bool operator>(const Node& a)

























    template class List




    Node *head;










    size_t length;




    List();




    void push(T *data);




    void push(T *data, int a);




    void push_s(T *data);




    T pop();

    T pop(size_t index);

    T pop_s();

    void sort();

    void save();

    void read();

    void clear();

    void print();

    void mass_print();

    bool isEmpty();











    Созданный класс List включает в себя, согласно варианту задания, динамический массив указателей, который содержит указатели на каждый 10-й элемент списка (0,10,20 и т.д.).

    Основные алгоритмы:

    1. Вставка в конец

    2. Вставка по индексу

    3. Вставка в начало

    4. Извлечение по индексу

    5. Сортировка

    6. Сохранение в бинарный файл

    7. Загрузка из бинарного файла

    8. Загрузка строк из текстового файла




      1. Вставка объекта в список

    Реализовано три способа вставки объекта. Первый способ — помещать новые элементы в конец списка. Второй — помещать новые элементы по логическому номеру. Третий — вставлять элементы с сохранением порядка, при этом список должен быть отсортирован.

    Элементы связанного списка являются структурами, так как, помимо данных, они содержат ссылку на следующий и предыдущий элементы. Поэтому нужно было определить структуру, которая представлена ниже:





    Рис 1.2 Вставка объекта в двусвязный список

      1. Удаление объекта

    Удаление элемента из двусвязного списка выполняется просто. Так же, как и при вставке, возможны три случая: удаление первого элемента, удаление элемента в середине, удаление последнего элемента.



    Рис 1.3 Операция «удаление по номеру»

    1. Функциональное описание

      1. List (Шаблонный класс)


    Поля: данные доступные для класса

    Node *Head; - указатель на первый добавленный элемент

    Node *Tail; - указатель на последний добавленный элемент

    int length; - количество элементов в списке

    bool sorted; - отсортирован ли список
    Конструктор и деструктор:

    • Конструктор

    List();

    Инициализирует поля Head, Tail, mass – указывая на NULL.


    • Конструктор с параметром

    List(T x);

    Инициализирует поля, при это добавляет в список объект


    • Конструктор копирования

    List(const List &C);

    Создает копию списка



    • Деструктор

    List();

    Очищает список


      1. Node (структура собственной разработки)


    Поля:

    • T *data; - указатель на объект

    • Node *next; - указатель на следующий элемент списка

    • Node *prev; - указатель на предыдущий элемент списка

      1. Основные методы




    • Метод проверяет пустой список или нет, путем проверки значения указателя на начало списка

    template

    bool List::isEmpty() {

    return Head == nullptr;

    }
    Метод выводит на экран список, начиная с указателя Head и передвигаясь дальше по списку.
    template

    string List::print() {

    check();
    stringstream ss; // поток ввода-вывода со строкой в памяти
    for (Node * tmp = Head; tmp; tmp = tmp->next) {

    ss << " -> " << *tmp->data;

    }
    return ss.str();

    }

    Метод добавляет элемент в конец, проверяет случай, когда список пуст, происходит «перебрасывание» указателей. После этого происходит проверка, нужно ли добавлять указатель в ДМУ, увеличивает значение размера списка.
    template

    void List::push(T *data, size_t index) {

    if (index > length) {

    throw out_of_range("index too big!");

    }
    if (0 == index) {

    push_s(data);

    } else {

    Node *inserted = new Node(data);

    Node *tmp = Head;
    for (; --index; ) {

    tmp = tmp->next;

    }
    inserted->next = tmp->next;

    inserted->prev = tmp;

    tmp->next = inserted;
    length++;

    }

    }
    template

    void List::push(T *data) {

    push(data, length);

    }
    template

    void List::push_s(T *data) {

    Node *inserted = new Node(data);
    inserted->next = Head;

    Head = inserted;
    length++;

    }

    Сортирует список при помощи сортировки пузырьком, при этом сравниваются узлы списка при помощи оператора присваивания.
    template

    void List::sort()

    {

    check();
    T * data;
    for (Node * tmp1 = Head; tmp1 != nullptr; tmp1 = tmp1->next) {

    for (Node * tmp2 = Head; tmp2 != nullptr; tmp2 = tmp2->next) {

    if (*tmp1 > *tmp2) {

    data = tmp1->data;

    tmp1->data = tmp2->data;

    tmp2->data = data;

    }

    }

    }

    }

    Очищает список, если он не пуст, путем прохода по каждому элементу и удалению его.

    template

    void List::clear() {

    check();
    for (Node * tmp = Head->next; tmp != nullptr; tmp = tmp->next) {

    delete tmp->prev;

    }
    Head = (Tail = nullptr);
    length = 0;

    }
    Сохраняет список в бинарный файл. Для этого сначала записывается размер списка, затем в цикле от начала до конца списка- записывается размер объекта и сам объект.
    template

    void List::save() { //сохранение в бинарный

    Node *tmp = Head;

    fstream out("tmp.bin", ios::binary | ios::out);

    out.write((char*)&length, sizeof(length));

    for (; tmp != nullptr; tmp = tmp->next) {

    int size = sizeof(*tmp->data);

    out.write((char*)&size, sizeof(size));

    out.write((char*)&(*tmp->data), size * sizeof(char));

    }

    out.close();

    }
    Производит чтение из бинарного файла. Для этого сначала считывается размер списка, затем в цикле от начала до конца списка- считывается размер объекта и сам объект, после этого он добавляется в список.
    template

    void List::read() { //чтение из бинарного

    int size;

    int len;
    fstream in("tmp.bin", ios::binary | ios::in);

    in.read((char*)&len, sizeof(len));

    T* tmp = new T[len + 1];

    for (int i = 0; i < len; i++) {
    in.read((char*)&size, sizeof(size));

    in.read((char*)(&tmp[i]), size * sizeof(char));

    push(&tmp[i]);

    }

    length = len;

    in.close();

    }



    1. Описание пользовательского интерфейса

    Приложение создано в виде консоли, пользовательский интерфейс представлен в виде меню с основными операциями

    Выбор типа данных:

    Пользователь может выбрать тип данных из трех предложенных, а именно – целые числа, строки и Class.

    Вывод:

    Пользователь может вывести на экран объекты списка.

    Вставка в начало:

    При выборе этого пункта происходит вставка в начальную позицию в списке.

    Вставка в заданную позицию:

    При выборе этого пункта происходит вставка в заданную позицию в списке. Отсчет идет с 0-позиции.

    Вставка в конец:

    При выборе этого пункта происходит вставка в конечную позицию в списке.

    Сортировка:

    Происходит сортировка по возрастанию чисел, либо по первым буквам в типах данных char* и Class.

    Удаление по индексу:

    При выборе этого пункта происходит удаление по заданной позиции в списке. Отсчет идет с 0-позиции.

    Сортировка:

    При выборе этого пункта пользователь может сортировать список по убыванию.


    1. Описание работы программы

      1. Примеры работы программы

    Для удобного пользования программой было разработано меню, обеспечивающее демонстрацию всех основных функций.



    Рис 4.1 Меню программы

      1. Тестирование на время выполнения


    Ниже приведены замеры времени работы операций добавления, удаления и балансировки при различном количестве элементов.


    Размер (мс)

    Добавление (мс)

    Удаление (мс)

    Сортировка (мс)

    50

    125

    16

    1047

    100

    302

    24

    3402

    250

    1023

    45

    23941

    500

    4162

    78

    90932

    1000

    8149

    95

    128308

    Табл 1 Время работы операций

    Добавление



    Рис 4.1 График зависимости времени добавления от количества элементов

    Удаление



    Рис 4.2 График зависимости времени удаления от количества элементов

    Сортировка



    Рис 4.3 График зависимости времени сортировки от количества элементов

    Заключение

    В результате проведенной работы был разработан шаблонный класс, имеющий в качестве элементов списка указатели на объект. Реализованы методы создания файла, просмотра, добавления, удаления, обновления и сортировки объектов. Реализована специализация для оператора сравнения узлов списка.

    Реализован динамический массив указателей (ДМУ), который содержит указатели на каждый 10-ый элемент списка (0,10,20 и т.д.). При этом он используется в программе для того, чтобы ускорить извлечение и вставку по логическому номеру.

    Достоинством программы является наличие в качестве структуры данных верхнего уровня двусвязный список, который позволяет удобно управлять операциями над объектами.
    Список используемой литературы

    ГОСТ 2015 – 369. Язык программирования С++ – Изд-во: Бином. Бьерн Страуструп

    1. ГОСТ 2013 – 688. Освой самостоятельно C++ за 21 день. Седьмое издание – Изд-во: Вильямс Издательский дом. Сиддхартха Рао

    2. http://ermak.cs.nstu.ru/cprog - электронный учебник по дисциплине " Информатика". Романов E.Л.

    Приложение

    List.h
    #ifndef LIST_H

    #define LIST_H
    #include

    #include

    #include

    #include
    using namespace std;

    template class List // шаблон класса списков

    {

    struct Node // структура представляющая единичный элемент списка

    {

    T *data; // указатель на объект

    Node *next; // указатель на следующий элемент списка

    Node *prev; // указатель на предыдущий элемент списка

    Node(T * data) : data(data) {

    }
    bool operator >(const Node& a) {

    return *data > *(a).data ? 1 : 0;

    }

    };
    private: // данные доступные для класса

    Node *Head = nullptr; // указатель первый добавленный элемент

    Node *Tail = nullptr; // указатель на последний элемент
    public: // данные и методы доступные для пользователя класса

    size_t length = 0; // количество элементов в списке
    List(); // деструктор
    void push(T *data);

    void push(T *data, size_t index);//добавление по логическому номеру

    void push_s(T *data);//добавление в начало

    T pop();

    T pop(size_t index); // извлечение по логическому номеру

    T pop_s();

    void sort(); // сортировка

    void save(); // сохранить в бинарный файл

    void read(); // загрузить из бинарного файла

    void clear();// очистить список

    void check(size_t index = 0);
    string print();

    bool isEmpty(); // проверка состояния списка (если список не пуст)

    };
    template

    List::List() {

    clear(); // очистить список

    }
    template

    bool List::isEmpty() {

    return Head == nullptr;

    }
    template

    string List::print() {

    check();
    stringstream ss;
    for (Node * tmp = Head; tmp; tmp = tmp->next) {

    ss << " -> " << *tmp->data;

    }
    return ss.str();

    }
    template

    void List::push(T *data, size_t index) {

    if (index > length) {

    throw out_of_range("index too big!");

    }
    if (0 == index) {

    push_s(data);

    } else {

    Node *inserted = new Node(data); // создать новый указатель на элемент и выделяем память

    Node *tmp = Head;
    for (; --index; ) {

    tmp = tmp->next;

    }
    inserted->next = tmp->next;

    inserted->prev = tmp;

    tmp->next = inserted;
    length++; // увеличиваем количество элементов в списке

    }

    }
    template

    void List::push(T *data) {

    push(data, length);

    }
    template

    void List::push_s(T *data) {

    Node *inserted = new Node(data); // создать новый указатель на элемент и выделяем память
    inserted->next = Head;

    Head = inserted;
    length++; // увеличиваем количество элементов в списке

    }
    template

    void List::sort() // Сортировка

    {

    check();
    T * data;
    for (Node * tmp1 = Head; tmp1 != nullptr; tmp1 = tmp1->next) {

    for (Node * tmp2 = Head; tmp2 != nullptr; tmp2 = tmp2->next) {

    if (*tmp1 > *tmp2) {

    data = tmp1->data;

    tmp1->data = tmp2->data;

    tmp2->data = data;

    }

    }

    }

    }
    template

    T List::pop() {

    return pop(length - 1);

    }
    template

    T List::pop(size_t index) { // реализация извлечения текущего элемента

    check(index);
    if (index == 0) {

    return pop_s();

    }
    T * data;

    Node * tmp = Head;
    for (; index--; tmp = tmp->next);

    tmp->prev->next = tmp->next;

    data = tmp->data;
    length--;

    return *data; // вернуть данные удаленного элемента

    }
    template

    T List::pop_s() { // реализация извлечения текущего элемента

    check();
    T * data;

    Node * tmp = Head;
    Head = Head->next;

    data = tmp->data;
    delete tmp;
    length--;

    return *data; // вернуть данные удаленного элемента

    }
    template

    void List::clear() {

    check();
    for (Node * tmp = Head->next; tmp != nullptr; tmp = tmp->next) {

    delete tmp->prev;

    }
    Head = (Tail = nullptr);
    length = 0;

    }
    template

    void List::save() { //сохранение в бинарный

    Node *tmp = Head;

    fstream out("tmp.bin", ios::binary | ios::out);

    out.write((char*)&length, sizeof(length));

    for (; tmp != nullptr; tmp = tmp->next) {

    int size = sizeof(*tmp->data);

    out.write((char*)&size, sizeof(size));

    out.write((char*)&(*tmp->data), size * sizeof(char));

    }

    out.close();

    }
    template

    void List::read() { //чтение из бинарного

    int size;

    int len;
    fstream in("tmp.bin", ios::binary | ios::in);

    in.read((char*)&len, sizeof(len));

    T* tmp = new T[len + 1];

    for (int i = 0; i < len; i++) {
    in.read((char*)&size, sizeof(size));

    in.read((char*)(&tmp[i]), size * sizeof(char));

    push(&tmp[i]);

    }

    length = len;

    in.close();

    }
    template

    void List::check(size_t index)

    {

    if (isEmpty()) {

    throw exception("Список пуст!");

    }
    if (index >= length) {

    throw out_of_range("Индекс слишком велик!");

    }

    }
    #endif

    main.cpp

    #include

    #include

    #include

    #include "list.h"
    int main()

    {

    List list;

    string s;
    int k, size = 0;
    setlocale(LC_ALL, "Rus");
    while (true) try {

    cout << "Меню:" << endl

    << "1 - Вставка в конец" << endl

    << "2 - Вставка по индексу" << endl

    << "3 - Вставка в начало" << endl

    << "4 - Извлечение по индексу" << endl

    << "5 - Сортировка" << endl

    << "6 - Сохранить в бинарный" << endl

    << "7 - Загрузить из бинарного" << endl

    << "9 - Очистить список" << endl

    << "0 - Печать списка" << endl

    << endl;
    switch (_getch()) {

    // Вставка в конец

    case '1': {

    cout << "Введите строку: ";

    cin >> s;

    list.push(new string(s));

    break;

    }

    // Вставка по индексу

    case '2': {

    cout << "Введите строку: ";

    cin >> s;

    cout << "Введите индекс: ";

    cin >> k;

    list.push(new string(s), k);

    break;

    }

    // Вставка в начало

    case '3': {

    cout << "Введите строку: ";

    cin >> s;

    list.push_s(new string(s));

    break;

    }

    // Извлечение по индексу

    case '4': {

    cout << "Введите индекс: ";

    cin >> k;

    cout << "Удаленный объект " << list.pop(k) << endl;

    break;

    }

    // Сортировка

    case '5':

    {

    list.sort();

    break;

    }

    // Сохранение в бинарный файл

    case '6': {

    list.save();

    break;

    }

    // Запись из бинарного файла

    case '7': {

    list.read();

    break;

    }

    //
    case '9': {

    list.clear();

    cout << "Ок." << endl;

    break;

    }

    // Печать списка

    case '0': {

    cout << list.print() << endl;

    break;

    }
    default: {

    cout << "Нет такого пункта в мен.!" << endl;

    }

    }
    system("pause");

    system("cls");

    }

    catch(exception e) {

    cout << e.what() << endl;

    system("pause");

    system("cls");

    }
    return 0;

    }

    НОВОСИБИРСК 2018


    написать администратору сайта