Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Структуры и алгоритмы обработки данных. Сортировка массивов и динамические структуры (90

.pdf
Скачиваний:
5
Добавлен:
15.11.2022
Размер:
676.59 Кб
Скачать

if(i<=j) // если левый индекс меньше правого индекса, то обмен

{

swap(s_arr[i], s_arr[j]); // меняем правое и левое значение местами,

 

с помощью стандартной функции обмена

i++;

//увеличиваем значение индекса

j--;

//уменьшаем значение индекса

}

 

}

 

while (i<=j);

//разделение на подмассивы

if (i<last) //один подмассив

qs(s_arr, i, last); //изменение индекса от i-того до конечного

if (first<j) //второй подмассив

qs(s_arr, first, j); //изменение индекса от начального до j-того

}

void alg_2()

{

clock_t start=0,end=0; //переменная для хранения времени

float t1=0;

// для хранения затраченного времени

//задание размера матрицы

const int n=3500;

 

//объявление матрицы int a[n], i;

//генерация случайных чисел от min=1 до max=3500 // с заполнением ими матрицы

const int min=1, max=3500; srand (time(NULL)); for(i=0; i<n; i++)

a[i]=rand()%(max-min+2)+min; for(i=0; i<n; i++)

printf("\na[%d]=%d", i, a[i]); //вывод сгенерированного массива start=clock(); // начинаем замер времени

qs(a, 0, n-1); // <=== сортируем здесь end=clock(); // заканчиваем подсчет времени

t1=(float)(end-start) / CLK_TCK; // считаем затраченное время в секундах //вывод на экран отсортированного массива

for(i=0; i<n; i++) printf("\na[%d]=%d", i, a[i]);

printf("\nT=%lf\n", t1); // выводим время выполнения сортировки getch();

}

13

Сравнение эффективности алгоритмов и выводы

Алгоритм быстрой сортировки выполняет сортировку массива быстрее,

чем алгоритм обменной сортировки. Так, время выполнения обменной сорти-

ровки одномерного массива целых чисел размером 3500 элементов составило

75 миллисекунд, тогда как время выполнения быстрой сортировки - 4 миллисе-

кунды, т.е. быстрая сортировка выполняется в 19 раз быстрее обменной (рис. 1).

Пузырьковая

Быстрая

Рис. 1. Сравнение алгоритмов сортировки

Быстрая сортировка обладает более высокой скоростью обработки масси-

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

ковой сортировкой, которая имеет более простой программный код и может использоваться при решении задач сортировки небольших массивов.

14

Лабораторная работа № 2

Линейные динамические структуры данных

Цель работы - овладение практическими навыками организации и манипу-

лирования основными линейными динамическими структурами данных: односвяз-

ным и двусвязным списком, а также структурами, построенными на их основе.

Для выполнения лабораторной работы необходимо:

1.Изучить:

-объявление и использование динамических переменных и указателей;

-способы организации выбранной в соответствии с вариантом задания ди-

намической структуры при помощи структур и указателей;

-правила обхода, добавления и удаления элементов для выбранной структуры.

2.Разработать программу, реализующую ввод, вывод и основные операции,

применимые для выбранной линейной динамической структуры.

3.Подготовить демонстрационный пример создания и несколько примеров операций для выбранной структуры.

4.Подготовить отчет, содержащий:

-титульный лист;

-задание;

-описание выбранного варианта линейной динамической структуры и возможных операций с ней (с примерами);

-блок-схему алгоритмов операций;

-текст программы;

-пример выполнения программы;

-выводы по работе;

-список использованной литературы.

15

1.Задание к работе

1.Выбрать из табл. 2 (вариант задается преподавателем) тип линейной ди-

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

кроме полей для связи хранит некоторое значение типа, выбранного в соответ-

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

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

бранного элемента из структуры или всей структуры. Организация структуры и все функции над ней реализуются в соответствии с правилами, заданными для конкретного типа структуры.

 

 

Таблица 2

 

 

 

 

Вариант

Тип структуры

Тип

 

задания

информационного поля

 

 

 

 

 

 

 

1

2

3

 

1

Стек

Целый

 

 

 

 

 

2

Дек

Целый

 

 

 

 

 

3

Очередь

Целый

 

 

 

 

 

4

Односвязный список

Целый

 

 

 

 

 

5

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

Целый

 

 

 

 

 

6

Стек

Вещественный

 

 

 

 

 

7

Дек

Вещественный

 

 

 

 

 

8

Очередь

Вещественный

 

 

 

 

 

9

Односвязный список

Вещественный

 

 

 

 

 

10

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

Вещественный

 

 

 

 

 

16

 

 

Окончание табл. 2

 

 

 

 

1

2

3

 

11

Стек

Символьный

 

 

 

 

 

12

Дек

Символьный

 

 

 

 

 

13

Очередь

Символьный

 

 

 

 

 

14

Односвязный список

Символьный

 

 

 

 

 

15

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

Символьный

 

 

 

 

 

16

Стек

Строка

 

 

 

 

 

17

Дек

Строка

 

 

 

 

 

18

Очередь

Строка

 

 

 

 

 

19

Односвязный список

Строка

 

 

 

 

 

20

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

Строка

 

 

 

 

 

2.Методический пример выполнения работы

Организовать линейную динамическую структуру:

1.Дек.

2.Тип информационного поля: целый.

Описание метода решения задачи

В языках программирования существует способ выделения памяти под данные, который называется динамическим. В этом случае память под величи-

ны отводится во время выполнения программы. Использование динамических величин предоставляет разработчику ряд дополнительных возможностей. Во-

первых, подключение динамической памяти позволяет увеличить объем обра-

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

вать структуры данных переменного размера.

Работа с динамическими величинами связана с использованием еще од-

ного типа данных - ссылочного типа. Величины, имеющие ссылочный тип, на-

17

зываются указателями. Указатель содержит адрес поля в динамической памяти,

хранящего величину определенного типа. Сам указатель располагается в стати-

ческой памяти.

Динамическая структура называется деком (двухсторонняя очередь) или двунаправленным списком, если каждый узел её содержит два указателя: один указывает на предшествующий узел, другой - на последующий. Такие списки могут быть линейными и циклическими, а члены в них добавляются и удаляют-

ся с двух сторон (рис. 2).

Рис. 2. Дек и операции с деком

1. Создание дека

Создаваемый класс в разработанной программе называется deq. Он реа-

лизует функции вставки и удаления элементов в начало и конец дека. Для соз-

дания этого класса необходимо сначала создать структуру элемента с указате-

лем на следующий элемент. Такой структурой является структура Node.

При создании класса необходимо создать указатели на первый и послед-

ний элементы дека. Они прописываются как private, т. е. обращаться к этим ука-

зателям возможно только из методов класса deq. В общедоступной области дос-

тупа (public) прописываются методы класса, реализующие операции над деком.

18

Указателям изначально присваиваются пустые значения (NULL).

2. Добавление элемента в начало дека

Для добавления элемента в начало дека используется метод класса add.

Его параметром является добавляемый элемент b.

Создается новый элемент структуры Node(el). Элементу el присваивается значение введенного с клавиатуры числа. Для добавления элемента в начало дека необходимо, чтобы ячейка была пуста, поэтому проверяется условие нали-

чия в ячейке элемента. Если ячейка не пуста, то указатель на первый элемент переходит на следующую ячейку, в которую и будет записан элемент. Количе-

ство ячеек возрастает на 1.

3. Удаление элемента из начала дека

Для удаления элемента из начала дека используется метод класса delete.

Удаление элемента происходит по тому же алгоритму, но ячейка не про-

веряется на наличие элемента в нем. Элементу el присваивается указатель first

и указатель переходит в следующую ячейку. Затем элемент el удаляется и ко-

личество ячеек уменьшается на 1.

4. Добавление элемента в конец дека

Для добавления элемента в начало дека используется метод класса add_end. Его параметрами является добавляемый элемент b.

Необходимо создать новый элемент структуры Node(el). Элементу el

присваивается значение введенного с клавиатуры числа. Для добавления эле-

мента в конец дека необходимо, чтобы ячейка была пуста. Указатель на по-

следний элемент переходит на следующую ячейку, в которую и будет записан элемент. Далее указатель на последний элемент переходит на следующую ячейку, которой присваивается значение NULL. Количество ячеек возрастает на 1.

5. Удаление элемента из конца дека

Для удаления элемента из начала дека используется метод класса de-

lete_end.

19

Для удаления элемента из конца дека надо создать новый элемент струк-

туры Node(el). Элементу el присваивается указатель на первый элемент. Пока el

не примет значения NULL, элемент будет принимать значения следующего

элемента. Затем el удаляется и ссылке на последний элемент присваивается

значение el. Количество ячеек уменьшается.

6. Вывод всех элементов списка

Для вывода всех элементов дека используется метод класса add_prohod:

необходимо создать новый элемент структуры Node(first). Проверяется условие

истинности структуры first и выполняется переход к отображению элементов

списка.

7. Очистка всех элементов списка

Для очистки всех элементов дека используется метод класса del_clear.

Указатель this указывает на адрес созданного объекта класса first, функ-

ция free освобождает память (присваиваются пустые значения ячейкам).

Реализация дека и манипуляции с ним

#include <stdio.h> #include <conio.h> #include <stdlib.h> #include <locale.h> #include <windows.h>

struct Node //объявление структуры

{

char key; //поле структуры

Node *next; //указатели на структуру *next-следующий

};

class deq // создание пользовательского типа данных

{

private: // эти члены доступны только в функциях-членах объектах класса Node *first; //указатель структуры на левый конец

Node *last; //указатель структуры на правый конец

public: //указывает, что эти члены доступны из любой функции

deq() //функция класса

{

first=NULL; //присваиваем левому концу пустые значения

20

last=NULL; //присваиваем правому концу пустые значения

}

void deq::add(char b) //функция заполнения с левого конца

{

Node *el=new Node; //выделение памяти

el->key=b;

//присваиваем полю введенное значение

if (first==NULL) //если конец пустой

{

 

el->next=first; //следующему присваиваем значение левого конца

first=el;

//левому концу значение введенного элемента

last=first;

//правому концу присваиваем значения левого

}

 

else //если нет

{

 

el->next=first; //следующему элементу = значение левого конца

first=el;

//левому концу = значение введенного элемента

}

 

}

 

void deq::add_end(char b) //функция заполнения правого конца

{

 

Node *el=new Node; //выделение памяти el->key=b; //присваиваем полю введенное значение

last->next=el;

//следующей ячейке = значение введенного элемента

last=el; //правому концу присваивается значение введенного элемента

last->next=NULL; // = следующему значению правому концу пустое

}

 

void deq::del()

//функция удаления с левого конца

{

Node *el=new Node; //выделение памяти

el=first;

//значение левого конца помещаем во временную память

first=el->next; //левому концу присваиваем значение следующего

delete el;

//удаляем значение из временной памяти

}

 

void deq::del_end() //функция удаления с правого конца

{

Node *el = new Node; //выделение памяти

el=first; //значение правого конца помещаем во временную память while (el->next->next!=NULL) //пока не ноль

el=el->next; //следующий элемент = во временную память delete el->next; //удаляется следующий

last=el; //правому концу присваиваем значение временного last->next=NULL; //следующему элементу = пустую ячейку

21

}

void deq::del_clear() //функция очистки списка

{

free(this->first); //освобождаем память this->first=NULL; //присваиваем пустые значения

} //Указатель this указывает на адрес созданного объекта класса

void deq :: add_prohod(struct Node *first) //функция отображения списка

{

if (first) //если истина

printf("%d", first->key); //вывод списка if (first->next) //если истина

add_prohod(first->next); //назад к функции отображения списка

}

void deq :: add_menu() //меню

{

char p=1, b; //р-счетчик пунктов меню, b-переменная для введенного значения struct Node *first=NULL, *last=NULL; // правому и левому концу NULL while ((p>0)||(p<8)) //цикл меню (или)

{

printf("\nЧто

вы

хотите сделать?\n1.Добавить элемент

в ко-

нец\n2.Добавить элемент в начало\n3.Удалить элемент из начала");

 

printf("\n4.Удалить

элемент

из

конца\n5.Очиcтить

спи-

сок\n6.Вывести все элементы\n0.Выход\n");

 

 

 

p=_getch(); //ввод пунктов меню

 

 

 

switch (p)

 

 

 

 

 

{

 

 

 

 

 

case '1': // добавление элемента в конец списка

 

printf("\nВведите элемент, который хотите добавить:");

 

scanf_s("%d", &b); //ввод элемента

 

 

add_end(b); //переход на функцию

 

 

break;

 

 

 

 

 

case '2': // добавление элемента в начало списка

 

printf("\nВведите элемент, который хотите добавить:");

 

scanf_s("%d", &b); //ввод элемента

 

 

add(b);

//переход на функцию

 

 

break;

 

 

 

 

 

case '3': // удаление элемента из начала списка

 

if (this->first!=NULL) //если не ноль

 

del();

//переход на функцию удаления

 

else // если ноль список пуст printf("\nСписок пустой!!!");

break;

22

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]