Advertisement
Guest User

Untitled

a guest
Apr 18th, 2019
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.57 KB | None | 0 0
  1. #include <iostream>
  2. #include <time.h>
  3. #include <algorithm>
  4.  
  5. using namespace std;
  6.  
  7. struct LinearList { //структура данных, элемент списка
  8. int data; //данные элемента списка
  9. int index; //его индекс в списке
  10. LinearList *prev; //указатель на предыдущий элемент списка
  11. LinearList *next; //указатель на следующий элемент списка
  12. }* HEAD = NULL; //указатель на голову списка, сразу обнуляем, так как пока список пуст
  13.  
  14. int sizeList() { //функция возвращающая размер списка
  15. if (HEAD == NULL) return 0; //если список пуст, то его размер 0
  16. int size = 0;
  17. LinearList *item = HEAD; //указатель на начало списка
  18. while (item->next != HEAD) { //обходим список от начала до конца
  19. size++; //увеличиваем размер
  20. item = item->next; //перехожим к след. элементу
  21. }
  22. return size++; //возвращаем размер списка
  23. }
  24.  
  25. void addNode(int data, int pos) { //добавление элемента в список
  26. LinearList *item = new LinearList; //выделили память под новый элемент списка
  27. item->data = data; //присвоили элементу данные
  28. if (HEAD == NULL) { //если список пустой
  29. item->next = item; //то наш элемент становится началом списка
  30. item->prev = item;
  31. HEAD = item;
  32. }
  33. else {
  34. LinearList *tmp = HEAD;
  35. //иначе пробегаем по списку до последнего эемента
  36. for (int i = pos; i > 1; i--)
  37. tmp = tmp->next;
  38. //добавляем элемент в список между предыдущим и следующим
  39. tmp->prev->next = item;
  40. item->prev = tmp->prev;
  41. item->next = tmp;
  42. tmp->prev = item;
  43. }
  44. item->index = sizeList(); //присваиваиваем индексу последнего элемента размер списка
  45. }
  46.  
  47. void deleteNode(int pos) { //удаление элемента из списка
  48. if (HEAD == NULL) { //если начала списка указывает на ноль, то список пуст
  49. cout << "List is empty\n"; //и удалять нечего
  50. return;
  51. }
  52. if (HEAD == HEAD->next) { //если в списке всего 1 элемент, то удаляем его
  53. delete HEAD;
  54. HEAD = NULL;
  55. }
  56. else {
  57. LinearList *tmp = HEAD;
  58. for (int i = pos; i > 1; i--) //пробегаем список до элемента с нужным индексом
  59. tmp = tmp->next;
  60. if (tmp == HEAD) //если это первый элемент
  61. HEAD = tmp->next; //то указатель на следующий элемент списка это начало списка
  62. tmp->prev->next = tmp->next; //удаляем указатель на следующий элемент от текущего
  63. tmp->next->prev = tmp->prev; //удаляем указатель на предыдущий элемент от текущего
  64. delete tmp; //удаляем сам элемент
  65. }
  66. }
  67.  
  68.  
  69. void output() { //функция вывода списка на экран
  70. if (sizeList() == 0) { //если размер списка 0
  71. cout << "List is empty" << endl; //то выводим сообщение что он пустой
  72. }
  73. else {
  74. LinearList *item = HEAD;
  75. for (int i = sizeList(); i > 0; i--) { //пробегаем список от начала до конца
  76. cout << item->data << ' '; //выводим данные каждого элемента
  77. item = item->next;
  78. }
  79. cout << endl;
  80. }
  81. }
  82.  
  83. void rand_fil(int amount) { //заполняем список случайными данными
  84. for (int i=0; i < amount; i++)
  85. addNode(rand() % 100 - (double)(rand() % 100000) / 100000,i);
  86. }
  87.  
  88. void rand_fil_small_val(int amount) { //заполняем список случайными данными с малым разбросом, то есть почти отсортированными
  89. double a = rand() % 10000;
  90. for (int i=0; i < amount; i++) {
  91. if (rand() % 3 == 1)
  92. addNode(rand() % 10000, i);
  93. else
  94. addNode(a += rand() % 20, i);
  95. }
  96. }
  97.  
  98. void rand_fil_reverse(int amount) { //заполняем список случайными данными в обратном порядке
  99. double a = 50000;
  100. for (int i =0; i<amount; i++)
  101. addNode(a -= rand() % 75, i);
  102. }
  103.  
  104. LinearList* getNode(int idx) { //функция, возвращающая элемент списка по указанному индексу
  105. LinearList *item = HEAD;
  106. for (int i = idx; i > 0; i--) //обходим список до нужной нам позиции
  107. item = item->next;
  108. return item; //возвращаем найденный элемент
  109. }
  110.  
  111. void clearList() { //функция очистки списка
  112. for (int i =sizeList(); i > 0; i--) //пробегаем весь список и удаляем все узлы
  113. deleteNode(i);
  114. }
  115.  
  116.  
  117.  
  118.  
  119. void ShellsSort() { //сортировка Шелла
  120. unsigned i,j,step; //переменные циклов и шаг
  121. int tmp; //переменная для обмена данными
  122. for (step = sizeList() / 2; step > 0; step /= 2) //сортируем уменьшая шаг пополам
  123. for (i = step; i < sizeList(); i++) { //сортируем элементы
  124. tmp = getNode(i)->data; //записали в tmp данные i-го узла
  125. for (j = i; j >= step; j -= step) { //сравниваем его с данными элемента, находящегося на расстоянии шага от него
  126. if (tmp < getNode(j - step)->data) //если этот данные этого элемента меньше j-го
  127. getNode(j)->data = getNode(j - step)->data; //то меняем их местами
  128. else
  129. break;
  130. }
  131. getNode(j)->data = tmp; //меняем местами
  132. }
  133. }
  134.  
  135. void compareTimeSort(int size) {
  136. srand(time(NULL));
  137. double time = clock();
  138. clearList();
  139. rand_fil(size);
  140. ShellsSort();
  141. cout << endl<< " Time random: " << (clock() - time) / CLOCKS_PER_SEC << endl;
  142. time = clock();
  143. clearList();
  144. rand_fil_small_val(size);
  145. ShellsSort();
  146. cout << " Time almost sorted: " << (clock() - time) / CLOCKS_PER_SEC << endl;
  147. time = clock();
  148. clearList();
  149. rand_fil_reverse(size);
  150. ShellsSort();
  151. cout << " Time reverse sorted: " << (clock() - time) / CLOCKS_PER_SEC << endl;
  152. }
  153.  
  154.  
  155. int main() {
  156. srand(time(NULL));
  157. //предлагается выбрать вариант заполнения списка
  158. cout << "Please choose method to fill list:" << endl;
  159. cout << "Filling with random sizeListbers: (1)" << endl;
  160. cout << "Filling with almost sorted sizeListbers: (2)" << endl;
  161. cout << "Filling with reverse sorted sizeListbers: (3)" << endl;
  162. int n, k;
  163. //защита ввода
  164. while (!(cin >> n) || n < 1 || n > 3 || (cin.peek() != '\n')) {
  165. cin.clear();
  166. while (cin.get() != '\n');
  167. cout << "Incorrect method! Try again!" << endl;
  168. }
  169. //предлагается выбрать размер списка
  170. cout << "And now, please input amount of sizeListbers: " << endl;
  171. //защита ввода
  172. while (!(cin >> k) || k < 0 || (cin.peek() != '\n')) {
  173. cin.clear();
  174. while (cin.get() != '\n');
  175. cout << "Incorrect value of amount! Try again!" << endl;
  176. }
  177. //в зависимости от выбора список заполняется
  178. if (n == 1)
  179. rand_fil(k);
  180. if (n == 2)
  181. rand_fil_small_val(k);
  182. if (n == 3)
  183. rand_fil_reverse(k);
  184.  
  185. cout << "List: " << endl;
  186. output(); //выводится на экран сам список
  187. double time = clock(); //счетчик времени
  188. cout << "Sorted list:" << endl;
  189. ShellsSort(); //сортируем список
  190. output(); //выводим его на экран
  191. cout << " Time: " << (clock() - time) / CLOCKS_PER_SEC << endl; //выводим время его сортировки
  192. //внизу сравнение сортировок, по умолчанию закоментил, чтобы прога не грузилась долго
  193. /*cout << "Sorting speed comparison for 3 data types and 1000 elements" << endl;
  194. compareTimeSort(1000);
  195. cout << "Sorting speed comparison for 3 data types and 5000 elements" << endl;
  196. //compareTimeSort(5000);
  197. cout << "Sorting speed comparison for 3 data types and 10000 elements" << endl;
  198. //compareTimeSort(10000);*/
  199. system("pause");
  200. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement