Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.93/15: Рейтинг темы: голосов - 15, средняя оценка - 4.93
79 / 67 / 28
Регистрация: 22.04.2016
Сообщений: 384

Реализовать многопоточную сортировку динамического массива целых чисел

01.11.2016, 21:52. Показов 3203. Ответов 48
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть задание:
Написать программу, которая выполняет сортировку динамического массива целых чисел, количество элементов которого задает пользователь после соответствующего запроса. Реализовать однопоточную и многопоточную сортировку массива. Отсортированный массив записать в файл.

Все, что нужно реализовать для однопоточности - я сделал. Для однопоточной сортировки я реализовал быструю сортировку. А вот с многопоточной сортировкой беда (в данном случаи, я выбрал сортировку Шелла с применением последовательности Седжвика). Никак не получается.

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

Свой код прилагаю:
Файл ArraySorting.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <fstream>
#include <cstdlib>
#include <time.h>
#include <stdio.h>
#include <thread>
 
#define MAXSTACK 2048 // максимальный размер стека
 
using namespace std;
 
template <class T>
class ArraySorting
{
public:
    ArraySorting();
    ~ArraySorting();
    void setArraySize(T); // Задание размера массива
    void arrayInitialization(); // Инициализация массива
    void printArray(); // Вывод массива на екран
    void printArrayCopy(); // Вывод копии массива на екран
    void writeToFile(); // Запись массива в файл
    T increment(long inc[], long size); // Инкремент для сортировки Шелла с 
                                    // применением последовательности Седжвика                                 
    void shellSorting(); // Сортировка массива
    void qSortI(); // Сортировка Хоара
    void readFromFile(); // Чтение с файла
    void arrayCopys();
    void sorting(int s, long i, long j, long seq[40], long inc);
 
private:
    T *array; // Начальный массив
    T *arrayCopy; // Копия массива
    INT64 arraySize; // Размер массива
 
};
 
 
template <class T>
ArraySorting<T>::ArraySorting()
{
    array = new T[0];
    arrayCopy = new T[0];
}
 
template <class T>
ArraySorting<T>::~ArraySorting()
{
    delete[] array;
    //delete[] arrayCopy;
}
 
 
 
// Задание размера массива
template <class T>
void ArraySorting<T>::setArraySize(T size)
{
    arraySize = size;
}
 
// Инициализация массива
template <class T>
void ArraySorting<T>::arrayInitialization()
{
    srand(time(0));
 
    array = new T[arraySize];
 
    // Заполняем массив случайными цыфрами от 1 до 9
    for (int counter = 0; counter < arraySize; counter++)
    {
        array[counter] = 1 + rand() % 9;
    }
}
 
 
// Вывод массива на екран
template <class T>
void ArraySorting<T>::printArray()
{
    for (int counter = 0; counter < arraySize; counter++)
    {
        cout << array[counter] << " ";
    }
}
 
// Вывод копии массива на екран
template <class T>
void ArraySorting<T>::printArrayCopy()
{
    for (int counter = 0; counter < arraySize; counter++)
    {
        cout << arrayCopy[counter] << " ";
    }
}
 
// Запись массива в файл
template <class T>
void ArraySorting<T>::writeToFile()
{
    ofstream file;
    file.open("array.bin", ios::out | ios::binary);
    for (int counter = 0; counter < arraySize; counter++)
    {
        file.write((char *)&array[counter], sizeof(T));
    }
    file.close();
}
 
 
// Чтение из файла
template <class T>
void ArraySorting<T>::readFromFile()
{
    ifstream instrm("array.bin", ios::binary);
    int a = 0;
    // читаем числа по одному из файла и выводим 
    while (instrm.read((char *)&a, sizeof(T)))
        cout << a << ' ';
    cout << '\n';
 
}
 
 
template <class T>
void ArraySorting<T>::arrayCopys()
{
    arrayCopy = new T[arraySize];
    for (int counter = 0; counter < arraySize; counter++)
    {
        arrayCopy[counter] = array[counter];
    }
}
 
// Инкремент для сортировки Шелла с 
// применением последовательности Седжвика
template <class T>
T  ArraySorting<T>::increment(long inc[], long size)
{
    int p1, p2, p3, s;
    p1 = p2 = p3 = 1;
    s = -1;
    do {
        if (++s % 2) {
            inc[s] = 8 * p1 - 6 * p2 + 1;
        }
        else {
            inc[s] = 9 * p1 - 9 * p3 + 1;
            p2 *= 3;
            p3 *= 3;
        }
        p1 *= 2;
    } while (3 * inc[s] < size);
    return s > 0 ? --s : 0;
}
 
template <class T>
void ArraySorting<T>::sorting(int s, long i, long j, long seq[40], long inc)
{
    while (s >= 0)
    {
        // сортировка вставками с инкрементами inc[]
        inc = seq[s--];
        for (i = inc; i < arraySize; i++) {
            T temp = arrayCopy[i];
            for (j = i - inc; (j >= 0) && (arrayCopy[j] > temp); j -= inc)
                arrayCopy[j + inc] = arrayCopy[j];
            arrayCopy[j + inc] = temp;
        }
    }
}
 
// Сортировка массива
template <class T>
void ArraySorting<T>::shellSorting()
{
    long inc = 0;
    long i = 0;
    long j = 0;
    long seq[40];
    int s;
    // вычисление последовательности приращений
    s = increment(seq, arraySize);
        
        // Моя попытка сделать многопоточную сортировку
    thread first (sorting(s, i, j, seq, inc)); // Компилятор ругается на эту строчку
    first.join();
}
 
 
// Сортировка Хоара
template<class T>
void ArraySorting<T>::qSortI() {
    long i, j; // указатели, участвующие в разделении
 
    long lb, ub; // границы сортируемого в цикле фрагмента
    long lbstack[MAXSTACK], ubstack[MAXSTACK]; // стек запросов
    // каждый запрос задается парой значений,
    // а именно: левой(lbstack) и правой(ubstack)
    // границами промежутка
    long stackpos = 1; // текущая позиция стека
    long ppos; // середина массива
    T pivot; // опорный элемент
    T temp;
    lbstack[1] = 0;
    ubstack[1] = arraySize - 1;
    do {
        // Взять границы lb и ub текущего массива из стека.
        lb = lbstack[stackpos];
        ub = ubstack[stackpos];
        stackpos--;
        do {
            // Шаг 1. Разделение по элементу pivot
            ppos = (lb + ub) >> 1;
            i = lb; j = ub; pivot = array[ppos];
            do {
                while (array[i] < pivot) i++;
                while (pivot < array[j]) j--;
                if (i <= j) {
                    temp = array[i]; array[i] = array[j]; array[j] = temp;
                    i++; j--;
                }
            } while (i <= j);
            // Шаги 2, 3. Отправляем большую часть в стек и двигаем lb, ub
            if (i < ppos) { // правая часть больше
                if (i < ub) { // если в ней больше 1 элемента - нужно
                    stackpos++; // сортировать, запрос в стек
                    lbstack[stackpos] = i;
                    ubstack[stackpos] = ub;
                }
                ub = j; // следующая итерация разделения
                // будет работать с левой частью
            }
            else { // левая часть больше
                if (j > lb) {
                    stackpos++;
                    lbstack[stackpos] = lb;
                    ubstack[stackpos] = j;
                }
                lb = i;
            }
        } while (lb < ub);// пока в меньшей части более 1 элемента
    } while (stackpos != 0); // пока есть запросы в стеке
}
Файл main.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <stdio.h>
#include <cstdlib>
#include <time.h>
#include <fstream>
#include <thread>
#include "ArraySorting.h"
 
using namespace std;
 
int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(0, "");
 
    INT64 size;
    
    cout << "Введите размер массива: " << endl;
    cin >> size;
 
    ArraySorting<int> myArray;
    
 
    myArray.setArraySize(size);
    myArray.arrayInitialization();
    //myArray.printArray();
    
    myArray.arrayCopys();
    
    
 
    long t1 = clock();
    //myArray.shellSorting();
    thread first([&myArray](){myArray.qSortI(); });
    long t2 = clock();
    cout << "\ntime sorting: " << t2 - t1 << endl;
 
    first.join();
 
    //myArray.printArray();
    long t3 = clock();
    thread second([&myArray](){myArray.writeToFile(); });
    long t4 = clock();
 
    cout << "\ntime writing to file: " << t4 - t3 << endl;
    second.join();
    //myArray.readFromFile();
 
    long t5 = clock();
    
    
    myArray.shellSorting();
    long t6 = clock();
 
    cout << "\ntime paralel sorting: " << t6 - t5 << endl;
    
    //myArray.printArrayCopy();
 
    system("PAUSE");
 
    return 0;
}
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
01.11.2016, 21:52
Ответы с готовыми решениями:

Реализовать сортировку двумерного динамического массива
#include &quot;stdafx.h&quot; #include &lt;ctime&gt; #include &quot;stdafx.h&quot; #include &lt;ctime&gt; #include &lt;iostream&gt; #include &lt;iomanip&gt; using...

Реализовать «массив целых чисел». Обработать ошибки динамического выделения памяти. Переопределить опе
Реализовать класс «массив целых чисел». Обработать ошибки динамического выделения памяти. Переопределить оператор ++ для указателя на...

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

48
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
03.11.2016, 22:50
Студворк — интернет-сервис помощи студентам
В своём коде найди, где эта ошибка возникает.
0
79 / 67 / 28
Регистрация: 22.04.2016
Сообщений: 384
03.11.2016, 23:05  [ТС]
nd2, вот здесь:
C++
1
thread second(&ArraySorting<T>::shellSorting, this, array3, arraySize2);
Когда дохожу отладчиком к этой строчке и потом нажимаю F10, то выскакивает необработанное исключение.
0
 Аватар для Voivoid
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
03.11.2016, 23:22
Цитата Сообщение от GbaLog- Посмотреть сообщение
Но в С++ нет динамических массивов.
Цитата Сообщение от GbaLog- Посмотреть сообщение
В С++ подобное имитирует std::vector
Интересный взгляд на вещи Типа: "В C++ нет потоков, в C++ потоки имитирует std::thread", или скажем "В C++ нет работы с файлами, в C++ подобное имитирует std::iofstream", "В C++ нет сортировки, её имитирует std::sort".

Так что-ли?
1
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
03.11.2016, 23:44
Цитата Сообщение от Voivoid Посмотреть сообщение
Интересный взгляд на вещи
Как добавить объект в массив объектов?
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
03.11.2016, 23:48
Цитата Сообщение от Voivoid Посмотреть сообщение
Интересный взгляд на вещи
Языком не предусмотрен синтаксис и функционал расширяющихся массивов,
но данный функционал предоставляет стандартная библиотека.
Цитата Сообщение от Voivoid Посмотреть сообщение
В C++ нет потоков, в C++ потоки имитирует std::thread
В данном случае сама модель языка поддерживает многопоточность,
так что, начиная с C++11 можно сказать, что многопоточность в C++ есть,
а вот расширяющихся массивов как не было, так и нет.
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
03.11.2016, 23:51
Цитата Сообщение от igdev Посмотреть сообщение
Когда дохожу отладчиком к этой строчке и потом нажимаю F10, то выскакивает необработанное исключение.
И какое значение там у this ?
0
 Аватар для Voivoid
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
04.11.2016, 00:22
Цитата Сообщение от Croessmah Посмотреть сообщение
Языком не предусмотрен синтаксис и функционал расширяющихся массивов,
но данный функционал предоставляет стандартная библиотека.
Ну, мне не особо хочется спорить на тему терминологии, но мне кажется как-то странным не считать стандартную библиотеку частью языка.

А то иначе возможны интересные утверждения уровня "В С++ нет списков инициализации, их имитирует std::initializer_list" или "В C++ нет RTTI, его имитирует содержимое хедера typeinfo"
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
04.11.2016, 00:29
Цитата Сообщение от Voivoid Посмотреть сообщение
как-то странным не считать стандартную библиотеку частью языка.
Она является частью языка и, скажем так, дополняет его.
А иначе получается, что в главе Arrays
должны описываться массивы и std::array.
Всё-таки вектор не массив, вектор - контейнер,
реализующий функционал динамического массива (как структуры данных),
к тому же вектор опять не массив - он шаблон класса.
1
 Аватар для Voivoid
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
04.11.2016, 00:39
Цитата Сообщение от Croessmah Посмотреть сообщение
Всё-таки вектор не массив, вектор - контейнер, реализующий функционал динамического массива
Какая-то странная логика. Типа "std::list это не двусвязанный список, std::list - контейнер, реализующий функционал двусвязанного списка"? Или скажем "std::map это не ассоциативный массив, std::map - контейнер, реализующий функционал ассоциативного массива"? Так что-ли? К чему эти лишние слои абстракции?

Цитата Сообщение от Croessmah Посмотреть сообщение
к тому же вектор опять не массив - он шаблон класса.
От того, что в языке есть встроенный тип массив, то что, теперь массивов других типов быть что-ли не может?
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
04.11.2016, 00:50
Цитата Сообщение от Voivoid Посмотреть сообщение
К чему эти лишние слои абстракции?
Это не абстракции.
В языке есть конкретный тип данных - массив.
В языке нет типа данных - двусвязный список.
Имеются классы. Есть шаблоны классов.
В стандартной библиотеке есть конкретный
шаблон класса, который реализует список.
Но std::list != тип данный список.

Цитата Сообщение от Voivoid Посмотреть сообщение
теперь массивов других типов быть что-ли не может?
Структуры данных - могут,
типов больше быть не может.
Если где-нибудь в шаблоне забыть о том,
что массив != класс != указатель,
то можно отхватить по башке.
Цитата Сообщение от Voivoid Посмотреть сообщение
в языке есть встроенный тип массив
Бинго! Итого, есть тип массив, а есть еще и классы.
Класс != массив, какую бы структуру данных он там не реализовывал.
C++
1
std::is_array<std::vector<int>>::value//false =(
так что не нужно путать структуры данных с типами языка.
GbaLog- писал о массиве как о типе языка,
вы же сюда каким-то боком структуры данных приплели.

Предлагаю закончить.
0
 Аватар для Voivoid
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
04.11.2016, 01:07
Цитата Сообщение от Croessmah Посмотреть сообщение
типов больше быть не может.
О, что-то мне это видится в высшей степени сомнительным утверждением. Интересно что бы сказал на это Лука Карделли. Ну да ладно, это все оффтоп, так что да.

Цитата Сообщение от Croessmah Посмотреть сообщение
Предлагаю закончить.
Поддерживаю
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
04.11.2016, 05:01
Цитата Сообщение от igdev Посмотреть сообщение
Все вроде хорошо
Всё совсем не хорошо. Во-первых, после myArray.arrayCopys(); нужно инициализировать два массива, которые будешь в потоках сортировать:
C++
1
myArray.initializationTwoArrays();
Во-вторых, нужно их правильно инициализировать (разделить один массив на две части), а не как у тебя:
Цитата Сообщение от igdev Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
template <class T> void ArraySorting<T>::initializationTwoArrays() 
{ 
    array2 = new T[arraySize2]; 
    array3 = new T[arraySize2]; 
    for (int counter = 0; counter < arraySize2; counter++) 
    { 
         array2[counter] = arrayCopy[counter]; 
    } 
    for (int counter = arraySize2; counter < arraySize; counter++) 
    {
          array3[counter] = arrayCopy[counter];  // у array3 индексы должны с 0 начинаться, а не с arraySize2
    } 
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
template <class T>
void ArraySorting<T>::initializationTwoArrays()
{
    array2 = new T[arraySize2];
    array3 = new T[arraySize2];
 
    for (int counter = 0; counter < arraySize2; counter++)
    {
        array2[counter] = arrayCopy[counter];
    }
 
    for (int counter = 0, i = arraySize2; i < arraySize;    )
    {
        array3[counter++] = arrayCopy[i++];
    }
}
В-третьих, в shellSorting() непонятно что творится. После такой сортировки - в массивах мусор.

Добавлено через 5 минут
И не забудь, что размер исходного массива должен делиться на два без остатка.
1
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
04.11.2016, 12:54
Цитата Сообщение от Voivoid Посмотреть сообщение
"В C++ нет потоков, в C++ потоки имитирует std::thread"
http://en.cppreference.com/w/cpp/thread
Цитата Сообщение от cppreference
C++ includes built-in support for threads, mutual exclusion, condition variables, and futures.
Это встроенное средство.
Цитата Сообщение от Voivoid Посмотреть сообщение
"В C++ нет работы с файлами, в C++ подобное имитирует std::iofstream"
Есть, но std::i/o/fstream - это всего лишь высокоуровневая обертка над реальной работой с файлами.
Я немного покопался и думаю, что это всего-лишь обёртка над std::FILE.
Не стоит разводить холивар и на эту тему, я скажу, в С++ есть работа с файлами и она предоставляется STL.
Цитата Сообщение от Voivoid Посмотреть сообщение
"В C++ нет сортировки, её имитирует std::sort"
Какое это вообще отношение имеет к типам в С++?
Это алгоритм.

Об моём видении динамических массивов в С++ Вам уже Croessmah всё сказал.
А вообще, если навскидку подумать, то динамическим массивом называть можно то, что отхапывает себе доп. память сразу за последним элементом, а не то, что выделяет новый блок и туда все старые элементы переносит. Ну или, в самом страшном случае, если места нет, то отхапывает в другом месте и в последний элемент старого впечатывает указатель на новый, гораздо эффективнее, чем всё переносить.
0
79 / 67 / 28
Регистрация: 22.04.2016
Сообщений: 384
04.11.2016, 21:57  [ТС]
nd2, все (надеюсь, что все) замечания исправил/подправил.
Цитата Сообщение от nd2 Посмотреть сообщение
В-третьих, в shellSorting() непонятно что творится. После такой сортировки - в массивах мусор.
Да, действительно данная сортировка была не лучшим вариантом. Я заменил ее на рекурсивную сортировку Хоара. Но, после сортировки и слияния массивов, часть массива становиться отрицательными числами. В чем может быть причина в самой сортировке или в методе слияния двух массивов?

Файл ArraySorting.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <fstream>
#include <cstdlib>
#include <time.h>
#include <stdio.h>
#include <thread>
 
#define MAXSTACK 2048 // максимальный размер стека
 
using namespace std;
 
template <class T>
class ArraySorting
{
public:
    ArraySorting();
    ~ArraySorting();
    void setArraySize(T); // Задание размера массива
    void arrayInitialization(); // Инициализация массива
    void initializationTwoArrays(); // Инициализация двух массивов, 
                                    // которые являются половинами массива arrayCopy 
    void printArray(); // Вывод массива на екран
    void printArrayCopy(); // Вывод копии массива на екран
    void writeToFile(); // Запись массива в файл
    void qSortI(); // Сортировка Хоара
    void readFromFile(); // Чтение с файла
    void arrayCopys(); // Создаем копии массива array
    void sorting(); // Многопоточная сортировка
    void margeArrays(); // Слияние двух массивов array2 и array3 в массив result
    void quickSortR(T* a, long N); // Рекурсивная сортировка Хоара для многопоточности
 
private:
    T *array; // Начальный массив
    T *arrayCopy; // Копия массива
    T *array2; // Первая половина массива arrayCopy
    T *array3; // Вторая половина массива arrayCopy
    T *result; // Массив, в который будет записано 
                //результат слияния двух массивов array2 и array3 
    INT64 arraySize; // Размер массива
    INT64 arraySize2; // Размер массивов array2 и array3 
 
};
 
 
template <class T>
ArraySorting<T>::ArraySorting()
{
    array = new T[0];
    arrayCopy = new T[0];
    array2 = new T[0];
    array3 = new T[0];
}
 
template <class T>
ArraySorting<T>::~ArraySorting()
{
    delete[] array;
    //delete[] arrayCopy;
}
 
 
 
// Задание размера массива
template <class T>
void ArraySorting<T>::setArraySize(T size)
{
    arraySize = size;
    arraySize2 = arraySize / 2;
}
 
// Инициализация массива
template <class T>
void ArraySorting<T>::arrayInitialization()
{
    srand(time(0));
 
    array = new T[arraySize];
 
    // Заполняем массив случайными цыфрами от 1 до 9
    for (int counter = 0; counter < arraySize; counter++)
    {
        array[counter] = 1 + rand() % 9;
    }
}
 
// Разделение массива arrayCopy на два подмассива array2 и array3
template <class T>
void ArraySorting<T>::initializationTwoArrays()
{
    array2 = new T[arraySize2];
    array3 = new T[arraySize2];
 
    for (int counter = 0; counter < arraySize2; counter++)
    {
        array2[counter] = arrayCopy[counter];
    }
 
    for (int counter = 0, i = arraySize2; i < arraySize; counter++)
    {
        array3[counter++] = arrayCopy[i++];
    }
}
 
 
// Вывод массива на екран
template <class T>
void ArraySorting<T>::printArray()
{
    for (int counter = 0; counter < arraySize; counter++)
    {
        cout << array[counter] << " ";
    }
}
 
// Вывод копии массива на екран
template <class T>
void ArraySorting<T>::printArrayCopy()
{
    for (int counter = 0; counter < arraySize; counter++)
    {
        cout << result[counter] << " ";
    }
}
 
// Запись массива в файл
template <class T>
void ArraySorting<T>::writeToFile()
{
    ofstream file;
    file.open("array.bin", ios::out | ios::binary);
    for (int counter = 0; counter < arraySize; counter++)
    {
        file.write((char *)&array[counter], sizeof(T));
    }
    file.close();
}
 
 
// Чтение из файла
template <class T>
void ArraySorting<T>::readFromFile()
{
    ifstream instrm("array.bin", ios::binary);
    int a = 0;
    // читаем числа по одному из файла и выводим 
    while (instrm.read((char *)&a, sizeof(T)))
        cout << a << ' ';
    cout << '\n';
 
}
 
// Создаем массив arrayCopy, который будет 
// использоваться в многопоточной сортировке
template <class T>
void ArraySorting<T>::arrayCopys()
{
    arrayCopy = new T[arraySize];
    for (int counter = 0; counter < arraySize; counter++)
    {
        arrayCopy[counter] = array[counter];
    }
}
 
 
// Слияние двух массивов array2 и array3 в
// сортированный массив result
template <class T>
void ArraySorting<T>::margeArrays()
{
    result = new T[arraySize2 + arraySize2];
 
    int i = 0; // Индексы, которые указывают на первый 
    int j = 0; // необработанный элемент первого и второго массива
 
    int index = 0; // Индекс массива-результата, который указывает на 
                    // на позицию, которая будет заполнена нп текущем шаге
 
    // Повторяем сравнение элементов массивов array2 и array3 до тех пор
    // пока в каждом из них есть хотя бы один необработанный элемент
    while (i < arraySize2 && j < arraySize)
    {
        // В соответствии с тем, текущий элемент какого массива меньше,
        // записываем элемент в массив-результат и обновляем нужный индекс
        if (array2[i] < array3[j])
        {
            result[index] = array2[i];
            i++;
        }
        else
        {
            result[index] = array3[j];
            j++;
        }
        index++;
    }
 
    // Дописываем оставшиеся элементы одного из массива в массив результат
    while (i < arraySize2)
    {
        result[index] = array2[i];
        index++;
        i++;
    }
 
    while (j < arraySize2)
    {
        result[index] = array3[j];
        index++;
        j++;
    }
}
 
// Многопоточная сортировка
template <class T>
void ArraySorting<T>::sorting()
{
    
    //initializationTwoArrays();    
 
    thread first(&ArraySorting<T>::quickSortR, this, array2, arraySize2);
    thread second(&ArraySorting<T>::quickSortR, this, array3, arraySize2);
 
    first.join();
    second.join();
 
    margeArrays();
}
 
 
 
 
// Сортировка Хоара
template<class T>
void ArraySorting<T>::qSortI() {
    long i, j; // указатели, участвующие в разделении
 
    long lb, ub; // границы сортируемого в цикле фрагмента
    long lbstack[MAXSTACK], ubstack[MAXSTACK]; // стек запросов
    // каждый запрос задается парой значений,
    // а именно: левой(lbstack) и правой(ubstack)
    // границами промежутка
    long stackpos = 1; // текущая позиция стека
    long ppos; // середина массива
    T pivot; // опорный элемент
    T temp;
    lbstack[1] = 0;
    ubstack[1] = arraySize - 1;
    do {
        // Взять границы lb и ub текущего массива из стека.
        lb = lbstack[stackpos];
        ub = ubstack[stackpos];
        stackpos--;
        do {
            // Шаг 1. Разделение по элементу pivot
            ppos = (lb + ub) >> 1;
            i = lb; j = ub; pivot = array[ppos];
            do {
                while (array[i] < pivot) i++;
                while (pivot < array[j]) j--;
                if (i <= j) {
                    temp = array[i]; array[i] = array[j]; array[j] = temp;
                    i++; j--;
                }
            } while (i <= j);
            // Шаги 2, 3. Отправляем большую часть в стек и двигаем lb, ub
            if (i < ppos) { // правая часть больше
                if (i < ub) { // если в ней больше 1 элемента - нужно
                    stackpos++; // сортировать, запрос в стек
                    lbstack[stackpos] = i;
                    ubstack[stackpos] = ub;
                }
                ub = j; // следующая итерация разделения
                // будет работать с левой частью
            }
            else { // левая часть больше
                if (j > lb) {
                    stackpos++;
                    lbstack[stackpos] = lb;
                    ubstack[stackpos] = j;
                }
                lb = i;
            }
        } while (lb < ub);// пока в меньшей части более 1 элемента
    } while (stackpos != 0); // пока есть запросы в стеке
}
 
// Рекурсивня сортировка Хоара для многопоточности
template<class T>
void ArraySorting<T>::quickSortR(T* a, long N) {
    // На входе - массив a[], a[N] - его последний элемент. 
 
    long i = 0, j = N;   // поставить указатели на исходные  места
        T temp, p;
 
    p = a[N >> 1];    // центральный элемент 
 
    // процедура разделения 
    do {
        while (a[i] < p) i++;
        while (a[j] > p) j--;
 
        if (i <= j) {
            temp = a[i]; a[i] = a[j]; a[j] = temp;
            i++; j--;
        }
    } while (i <= j);
 
 
    // рекурсивные вызовы, если есть, что сортировать  
    if (j > 0) quickSortR(a, j);
    if (N > i) quickSortR(a + i, N - i);
}
Файл main.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <stdio.h>
#include <cstdlib>
#include <time.h>
#include <fstream>
#include <thread>
#include "ArraySorting.h"
 
 
using namespace std;
 
 
int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(0, "");
 
    INT64 size;
    
    cout << "Введите размер массива: " << endl;
    cin >> size;
 
    ArraySorting<int> myArray;
    
 
    myArray.setArraySize(size);
    myArray.arrayInitialization();
    //myArray.printArray();
    
    myArray.arrayCopys();
    myArray.initializationTwoArrays();
    myArray.printArray();
 
    //long t1 = clock();
    ////myArray.shellSorting();
    //thread first([&myArray](){myArray.qSortI(); });
    //long t2 = clock();
    //cout << "\ntime sorting: " << t2 - t1 << endl;
 
    //first.join();
 
    ////myArray.printArray();
    //long t3 = clock();
    //thread second([&myArray](){myArray.writeToFile(); });
    //long t4 = clock();
 
    //cout << "\ntime writing to file: " << t4 - t3 << endl;
    //second.join();
    ////myArray.readFromFile();
 
    long t5 = clock();
    
    
    myArray.sorting();
    long t6 = clock();
 
    cout << "\ntime paralel sorting: " << t6 - t5 << endl;
    
    myArray.printArrayCopy();
 
    system("PAUSE");
 
    return 0;
}
Миниатюры
Реализовать многопоточную сортировку динамического массива целых чисел  
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
04.11.2016, 22:56
Цитата Сообщение от igdev Посмотреть сообщение
C++
1
2
3
4
for (int counter = 0, i = arraySize2; i < arraySize; counter++) 
{ 
     array3[counter++] = arrayCopy[i++];
}
Я разве так показывал (в initializationTwoArrays())?

Добавлено через 4 минуты
Цитата Сообщение от igdev Посмотреть сообщение
В чем может быть причина в самой сортировке или в методе слияния двух массивов?
В сортировке. После неё, в нулевых элементах - мусор.
0
79 / 67 / 28
Регистрация: 22.04.2016
Сообщений: 384
04.11.2016, 23:01  [ТС]
nd2, исправил. Но проблема осталась.
Миниатюры
Реализовать многопоточную сортировку динамического массива целых чисел  
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
04.11.2016, 23:02
Цитата Сообщение от igdev Посмотреть сообщение
// На входе - массив a[], a[N] - его последний элемент.
Последний элемент - a[N - 1].
1
79 / 67 / 28
Регистрация: 22.04.2016
Сообщений: 384
04.11.2016, 23:02  [ТС]
Цитата Сообщение от nd2 Посмотреть сообщение
В сортировке. После неё, в нулевых элементах - мусор.
Как же его можно убрать?
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
04.11.2016, 23:02
Цитата Сообщение от igdev Посмотреть сообщение
исправил.
Что исправил? Сортировку?
0
79 / 67 / 28
Регистрация: 22.04.2016
Сообщений: 384
04.11.2016, 23:02  [ТС]
Понял. Сейчас.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
04.11.2016, 23:02
Помогаю со студенческими работами здесь

Реализовать линейный однонаправленный список на базе массива целых чисел
1.Дан одномерный массив случайным образом заданных целых чисел. Из элементов массива построить линейный однонаправленный список. ...

Используем двумернный динамического массив целых чисел
Используем двумернный динамического массив целых чисел размера n * m вводит пользователь.элементы массива вводит сам пользователь и...

Реализовать сортировку массива структур по заданному полю
Помогите правильно отсортировать структуры по среднему балу и записать их в файл структура: struct student { char name; int...

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

Реализовать и протестировать функцию создания двумерного динамического массива
Ребята , помогите решить задачу : Реализовать и протестировать функцию создания двумерного динамического массива. Функция должна иметь...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru