Сортировка Шелла - Assembler

Узнай цену своей работы

Формулировка задачи:

Мне нужно написать курсовую на тему сортировка Шелла Я видел на сайте код для неё, но так и не понял как сделать её рабочей. Есть у меня уже готовый код, с меню, красиво оформлено, только для сортировки Гнома, и никак не могу переделать её на Шелла. Может кто шарит и поможет переделать? Я так понимаю нужно только GnomeSort поменять на алгоритм Шелла, но я так и не разобрался как Вот код для Гнома
Листинг программы
  1. ;---------------------------------------------------------------------
  2. ; Підпрограма запису цілого числа з клавіатури з перевіркою на знак
  3. ;---------------------------------------------------------------------
  4. ; Параматри
  5. ; ax - введене число
  6. ;---------------------------------------------------------------------
  7. InputPInt proc
  8. ;збереження значень регістрів у стек
  9. push dx
  10. push bx
  11. push cx
  12. push si
  13. push di
  14. push ds
  15. push cs
  16. pop ds
  17. ;при невдалому введенні спробувати знову
  18. @@again:
  19. PRINT "==> "
  20. ;функція вводу символу з клавіатури
  21. mov ah,0ah
  22. xor di,di
  23. mov dx, offset @@buff
  24. int 21h
  25. mov dl,0ah
  26. mov ah,02
  27. int 21h
  28. ;обробляємо значення буфера
  29. ;адрес початку строки
  30. mov si, offset @@buff+2
  31. cmp byte ptr [si], "-" ;перевірка першого символу на мінус
  32. jnz @@ii1
  33. jmp @@er
  34. @@ii1:
  35. xor ax, ax
  36. mov bx, 10 ;ініціалізація основи системи числення
  37. @@ii2:
  38. mov cl,[si] ;беремо символ з буферу
  39. cmp cl,0dh ;перевіряємо, чи не останній він
  40. jz @@enddecin
  41. ;якщо символ не останній, перевіряємо на правильність вводу
  42. cmp cl,'0'
  43. jl @@er
  44. cmp cl,'9'
  45. ja @@er
  46. ;перетворюємо символ в 10-ве число
  47. sub cl,'0'
  48. mul bx
  49. add ax,cx
  50. inc si
  51. jmp @@ii2
  52. ;вивід повідомлення про помилку вводу
  53. @@er:
  54. PRINTN "Invalid number!Try again."
  55. jmp @@again
  56. @@enddecin:
  57. ;відновлюємо значення регістів
  58. cmp ax, 0
  59. je @@er
  60. pop ds
  61. pop di
  62. pop si
  63. pop cx
  64. pop bx
  65. pop dx
  66. ret
  67. @@buff db 6,7 Dup(?)
  68. InputPInt endp
  69. ;---------------------------------------------------------------------
  70. ;Підпрограма запису відповіді в файл
  71. ;---------------------------------------------------------------------
  72. ;Параматри:
  73. ; нічого
  74. ;---------------------------------------------------------------------
  75. InputToFile proc
  76. ;Відкриваємо файл
  77. mov ah,3ch
  78. xor cx, cx
  79. lea dx, fn
  80. int 21h
  81. ;При помилці відкриття виходимо
  82. jc @exit
  83. mov dscr, ax
  84. mov si, 0 ;ітератор
  85. mov di, count
  86. ;ініціалізуємо цикл
  87. @@again:
  88. cmp di, 0
  89. je @exit
  90. ;вибираємо число з масиву
  91. xor cx,cx
  92. mov ax, array[si]
  93. add si, 2
  94. ;якщо число відємне, то приводимо його до відповідного типу
  95. test ax, ax
  96. jns pos
  97. neg ax
  98. push ax
  99. push bx
  100. push cx
  101. push dx
  102. mov ah, 40h
  103. mov bx, dscr
  104. mov cx, 1
  105. mov dx, offset minus
  106. int 21h
  107. pop dx
  108. pop cx
  109. pop bx
  110. pop ax
  111. ;інакше продовжуємо
  112. pos:
  113. ;перетворюємо число
  114. mov bx, 10
  115. div10:
  116. xor dx,dx
  117. div bx
  118. push dx
  119. inc cx
  120. or ax, 0
  121. jnz div10
  122. mov dx, cx
  123. xor bx, bx
  124. nxt:
  125. pop ax
  126. add ax, 30h
  127. mov buf[bx], ax
  128. inc bx
  129. loop nxt
  130. ;записуємо переведене число в файл
  131. mov ah, 40h
  132. mov bx, dscr
  133. mov cx, dx
  134. lea dx, buf
  135. int 21h
  136. ;записуємо пробіл
  137. mov ah, 40h
  138. mov bx, dscr
  139. mov cx, 1
  140. mov dx, offset space
  141. int 21h
  142. ;декрементуємо di та при необхідності повторюємо
  143. dec di
  144. jmp @@again
  145. @exit:
  146. ret
  147. InputToFile endp
  148. ;--------------------------------------------------------------------
  149. ;Підпрограма сортування масиву DWORD алгоритмом "гнома"
  150. ;-------------------------------------------------------------------
  151. ;Параматри:
  152. ; array - покажчик на масиву
  153. ; count - кількість елементів у масиві
  154. ;--------------------------------------------------------------------
  155. GnomeSort proc
  156. push BP
  157. mov BP, SP
  158. push BX
  159. push SI
  160. push DI
  161. ;xor si, si
  162. mov CX, count ;заносимо в ECX кількість елементів массиву
  163. xor AX, AX ;обнулюємо АХ, який буде ітератором
  164. xor si, si
  165. MainLoop:
  166. ;Якщо 'i' >= кількості елементів, то виходисо з циклу
  167. cmp AX, CX
  168. jge EndLoop
  169. ;Якщо 'i' == 0, перейти до наступного елементу
  170. cmp AX, 0
  171. je IncreaseCounter
  172. ;Якщо array[i-1] <= array[i], це означає що массив є відсортованим, отже переводимо до наступного елементу
  173. mov BX, array[SI]
  174. mov DX, array[SI-2]
  175. cmp DX, BX
  176. jle IncreaseCounter
  177. ;Інакше міняємо місцями array[i-1] з array[i]
  178. push array[SI]
  179. push array[SI-2]
  180. pop array[SI]
  181. pop array[SI-2]
  182. ;Переходимо до попереднього елементу в масиві і декрементуємо АХ
  183. sub SI, 2
  184. dec AX
  185. BackToMainLoop:
  186. jmp MainLoop
  187. ;Переходимо до наступного елементу в масиві і інкрементуємо АХ
  188. IncreaseCounter:
  189. inc AX
  190. add SI, 2
  191. jmp BackToMainLoop
  192. EndLoop:
  193. ;Відновлюємо регістри
  194. pop DI
  195. pop SI
  196. pop BX
  197. pop BP
  198. GnomeSort endp
  199. ;--------------------------------------------------------------
  200. ; Підпрограма запису цілого 10-числа з клавіатури
  201. ;--------------------------------------------------------------
  202. ; Параматри
  203. ; ax - введене число
  204. ;--------------------------------------------------------------
  205. InputInt proc
  206. ;збереження значень регістрів у стек
  207. push dx
  208. push bx
  209. push cx
  210. push si
  211. push di
  212. push ds
  213. push cs
  214. pop ds
  215. ;при невдалому введенні спробувати знову
  216. again:
  217. PRINT "==>"
  218. ;функція вводу символу з клавіатури
  219. mov ah,0ah
  220. xor di,di
  221. mov dx, offset buffs
  222. int 21h
  223. mov dl,0ah
  224. mov ah,02
  225. int 21h
  226. ;обробляємо значення буфера
  227. ;адрес початку строки
  228. mov si, offset buffs+2
  229. cmp byte ptr [si], "-" ;перевірка першого символу на мінус
  230. jnz ii1
  231. mov di,1
  232. inc si
  233. ii1:
  234. xor ax,ax
  235. mov bx,10 ;ініціалізація основи системи числення
  236. ii2:
  237. mov cl,[si] ;беремо символ з буферу
  238. cmp cl,0dh ;перевіряємо, чи не останній він
  239. jz enddecin
  240. ;якщо символ не останній, перевіряємо на правильність вводу
  241. cmp cl,'0'
  242. jl er
  243. cmp cl,'9'
  244. ja er
  245. ;перетворюємо символ в 10-ве число
  246. sub cl,'0'
  247. mul bx
  248. add ax,cx
  249. inc si
  250. jmp ii2
  251. ;вивід повідомлення про помилку вводу
  252. er:
  253. PRINTN "Invalid number!Try again."
  254. jmp again
  255. ;якщо встановлений флаг, то робимо число відємним
  256. enddecin:
  257. cmp di,1
  258. jnz ii3
  259. neg ax
  260. ii3:
  261. ;відновлюємо значення регістів
  262. pop ds
  263. pop di
  264. pop si
  265. pop cx
  266. pop bx
  267. pop dx
  268. ret
  269. buffs db 6,7 Dup(?)
  270. InputInt endp
  271. ;--------------------------------------------------------------
  272. ;Підпрограма виводу цілого 10-го числа
  273. ;--------------------------------------------------------------
  274. ; Параматри:
  275. ; ах - чило для виводу
  276. ;--------------------------------------------------------------
  277. OutInt proc
  278. ;Зберігаємо значення регістрів
  279. push ax
  280. push dx
  281. push bx
  282. push cx
  283. push ds
  284. push di
  285. push cs
  286. pop ds
  287. ;Перевіряємо число на знак
  288. test ax, ax
  289. jns oi1
  290. mov di, 1
  291. neg ax
  292. oi1:
  293. xor cx, cx
  294. mov bx, 10 ;основа СЧ
  295. oi2:
  296. xor dx, dx
  297. div bx
  298. add dx, '0'
  299. push dx ;зберігаємо значення в стек
  300. inc cx
  301. ;Відділяємо цифру справа поки не залишиться 0
  302. test ax, ax
  303. jne oi2
  304. ;Виводимо отримане значення
  305. mov ah, 2
  306. cmp di, 1
  307. jne oi3
  308. ;При відємному числі виводимо знак '-'
  309. mov dl, '-'
  310. int 21h
  311. oi3:
  312. pop dx ;Виштовхеємо цифру, переводимо її в символ і виводимо
  313. int 21h
  314. loop oi3 ;повторюємо стільки разів, скільки цифр було нараховано
  315. ;Відновлюємо значення регістрів
  316. pop di
  317. pop ds
  318. pop cx
  319. pop bx
  320. pop dx
  321. pop ax
  322. ret
  323. OutInt endp
  324. ;-------------------------------------------------------------
  325. ; Підпрограма заповнення массива з клавіатури
  326. ;-------------------------------------------------------------
  327. ; Параматри:
  328. ; сх - кількість елементів у масиві
  329. ;-------------------------------------------------------------
  330. GetArray proc
  331. mov cx, count ;довжина массива
  332. mov bx, 0 ;ітератор
  333. @@1:
  334. call InputInt
  335. mov array[bx], ax
  336. add bx, 2
  337. loop @@1
  338. ret
  339. GetArray endp
  340. ;------------------------------------------------------------
  341. ; Підпрограма виводу масиву на консоль
  342. ;------------------------------------------------------------
  343. ; Параматри
  344. ; сх - довжина массива
  345. ;------------------------------------------------------------
  346. OutArray proc
  347. cmp count, 0
  348. je @@Exit
  349. mov cx, count ;довжина массива
  350. mov bx, 0
  351. mov dl, ' '
  352. @@2:
  353. mov ax, array[bx]
  354. call OutInt
  355. mov ah, 2
  356. int 21h
  357. add bx, 2
  358. loop @@2
  359. @@Exit:
  360. ret
  361. OutArray endp
  362. ;-----------------------------------------------------------------
  363. ;Процедура відкриття файлу
  364. ;-----------------------------------------------------------------
  365. ;Параматри
  366. ; немає
  367. ;-----------------------------------------------------------------
  368. OpenFileRead PROC
  369. mov ah,3dh
  370. mov al,0
  371. int 21h
  372. ret
  373. OpenFileRead ENDP
  374. ;-------------------------------------------------------------
  375. ;Процедура закриття файлу
  376. ;------------------------------------------------------------
  377. ;Параматри:
  378. ; BX декриптор файла
  379. ;-------------------------------------------------------------
  380. CloseFile PROC
  381. mov ah,3eh
  382. int 21h
  383. ret
  384. CloseFile ENDP
  385. ;------------------------------------------------------------------
  386. ;Процедура виходу з проограми
  387. ;------------------------------------------------------------------
  388. ;Параматри:
  389. ; немає
  390. ;----------------------------------------------------
  391. ExitProgramm PROC
  392. mov ah,0
  393. mov al,2
  394. int 10h
  395. mov ah,04Ch
  396. mov al,0h
  397. int 21h
  398. ExitProgramm ENDP
  399. ;------------------------------------------------------------------------
  400. ;Процедура вивиду рядку символів на екран
  401. ;------------------------------------------------------------------------
  402. ;Параматри:
  403. ; bx - символ для виводу
  404. ;------------------------------------------------------------------------
  405. WriteStr PROC
  406. mov ah,09h
  407. int 21h
  408. ret
  409. WriteStr ENDP
  410.  
  411. ;-----------------------------------------------------------------------
  412. ;функція читання з файлу
  413. ;----------------------------------------------------------------------
  414. ReadFromFile proc
  415. ;Відкриваємо файл
  416. mov dx, offset fname
  417. call OpenFileRead
  418. mov handle, ax
  419. mov buff, 0
  420. mov position, 0
  421. xor si, si
  422. xor di, di
  423. @@again:
  424. ;--------------------------------------------------------------------
  425. ;Покажчик на потрібну позицію
  426. mov bx, handle
  427. mov al, 0
  428. mov cx, 0
  429. mov dx, position
  430. mov ah, 42h
  431. int 21h
  432. inc position ;Зміщуємо позицію
  433. ;Читаємо з файлу
  434. mov bx, handle
  435. mov ah, 3fh
  436. mov cx, 1 ;Зчитуємо по 1 байту
  437. mov dx, offset t_buff
  438. int 21h
  439. ;Перевіряємо на кінець файлу
  440. cmp t_buff, '$'
  441. je Exit
  442. ;Перевіряємо на відємне число
  443. cmp t_buff, '-'
  444. jne @@postv
  445. mov di, 1
  446. jmp @@again
  447. @@postv:
  448. ;Перевіряємо на пробіл
  449. cmp t_buff, ' '
  450. jne @@cont
  451. ;Якщо пробіл, записуємо значення в масив
  452. cmp position, 3
  453. jne @@ncount
  454. push buff
  455. pop count
  456. mov buff, 0
  457. jmp @@again
  458. @@ncount:
  459. cmp di,1
  460. jne @@pos
  461. mov bx, buff
  462. neg bx
  463. mov buff, bx
  464. @@pos:
  465. mov bx, buff
  466. mov array[si], bx
  467. add si, 2 ;Зміщуємо позицію
  468. mov buff, 0
  469. xor di, di
  470. jmp @@again
  471. @@cont:
  472. xor ch, ch
  473. mov cl, t_buff
  474. ;перевіряємо на правильність вводу
  475. cmp cl,'0'
  476. jl Exit
  477. cmp cl,'9'
  478. ja Exit
  479. ;початкові установки
  480. mov bx, 10 ;ініціалізація основи системи числення
  481. ;перетворюємо символ в 10-ве число
  482. sub cl,'0'
  483. xor ch, ch
  484. mov ax, buff
  485. mul bx
  486. add ax, cx
  487. mov buff, ax
  488. jmp @@again
  489. Exit:
  490. mov bx, handle
  491. Call CloseFile
  492. jc Exit
  493. ret
  494. ReadFromFile endp

Решение задачи: «Сортировка Шелла»

textual
Листинг программы
  1. // BaseType - любой перечисляемый тип
  2. // typedef int BaseType - пример
  3. void ShellsSort(BaseType *A, unsigned N)
  4. {
  5.     unsigned i,j,k;
  6.     BaseType t;
  7.     for(k = N/2; k > 0; k /=2)
  8.         for(i = k; i < N; i++)
  9.         {
  10.             t = A[i];
  11.             for(j = i; j>=k; j-=k)
  12.             {
  13.                 if(t < A[j-k])
  14.                     A[j] = A[j-k];
  15.                 else
  16.                     break;
  17.             }
  18.             A[j] = t;
  19.         }
  20. }

Объяснение кода листинга программы

  1. Входные данные:
    • A - указатель на массив, который необходимо отсортировать
    • N - количество элементов в массиве A
  2. Создаются три переменные:
    • i - счётчик, который будет использоваться в двух вложенных циклах
    • j - счётчик, который будет использоваться во внутреннем цикле
    • k - делитель, который будет применяться к N во внутреннем цикле
  3. Запускается внешний цикл, который будет выполняться до тех пор, пока k не станет равным 1:
    • Текущее значение k вычитается из i во внутреннем цикле
    • Во внутреннем цикле происходит перебор элементов массива A, начиная с элемента с индексом j-k
    • Если текущий элемент A[j-k] больше t, то A[j] присваивается значение A[j-k]
    • Если текущий элемент A[j-k] меньше или равен t, то цикл прерывается
    • После выхода из внутреннего цикла, A[j] присваивается значение t
  4. По завершении внешнего цикла, массив A будет отсортирован в порядке возрастания.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

15   голосов , оценка 3.933 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы