Қазақстан республикасының бiлiм және ғылым министрлiгi



бет10/14
Дата18.12.2021
өлшемі0,78 Mb.
#102591
1   ...   6   7   8   9   10   11   12   13   14
Байланысты:
364bd4d0-c314-11e5-bf37-f6d299da70eeМетод лекцииМСП

07

112

115

333

119

442

салыстыру 19 және 42, орындарын ауыстырамыз

07

112

115

119

333

442

салыстыру 19 және 33, орындарын ауыстырамыз

07

112

115

119

333

442

салыстыру 19 және 15, ауыстыру жоқ, 15 – үшінші минималды.

қадам4

07

112

115

119

333

442

салыстыру 42 және 33, ауыстыру жоқ

07

112

115

119

333

442

салыстыру 33 және 19, ауыстыру жоқ, 19 – төртінші элемент.

қадам 5

07

112

115

119

333

442

салыстыру 42 және 33, ауыстыру жоқ, сұрыптау аяқталды

 

07

112

115

119

333

442

 

 

Нәтижесінде , алты элемент үшін 5+4+3+2+1 = 15 салыстыру және 8 орын ауыстырулар өткізілді.

Жалпы жағдайда, әр n-1 қадамда орташа n/2 салыстырулар өткізіледі, сондықтан салыстырулар саны үшін бағалау n(n-1)/2 жазбасымен бейнеленеді, яғни берілген әдіс O(n2) классына байланысты. Аналогті түрде, орын ауыстырулар саны да n2 мәніне пропорционалды. Бұл әдіс ең тиімді емес сұрыптау әдісі болып табылады. Мысалы, 1000 элементтер үшін салыстырулар саны 500 мыңға жұық болады.

Бағдарламалық түрде іске асыру екі циклдан тұрады: сыртқы нәтижі –алгоритмнің негізгі қадамдары, ішкі – элементтерді салыстырады және орындарын массивтің соңынан бастап ауыстырады.

Көбікше әдістің бағдарламасының негізгі фрагменті:

for i := 2 to n do

begin

for j := n downto i do

if a[j-1] > a[j] then

begin temp := a[j-1]; a[j-1] := a[j]; a[j] := temp; end;

end;

Бағдарлама 1. Көбікше әдіс А

program puz_sort;

(*көбікше сұрыптау әдісі*)

const N=5;

type item: integer;

var a: array [1..n] of item; i, j: integer; x: item;

begin (*бастапқы массивті беру*)

for i:=1 to N do begin write ('элемент еңгізу a [', i, ']= ');

readln (a[i]);

end;

for i:=1 to N do begin write (a[i], ' ');



end;

writeln;

(*көбікше сұрыптаудың алгоритмі*)

for i:=2 to n do for j:=n downto i do begin

if a [j‑1]>a[j] then begin x:=a [j‑1]; a [j‑1]:=a[j]; a[j]:=x;

end;


end;

(*сұрыпталған массивті шығару*)

for i:=1 to N do begin write (a[i], ' ');

end;


readln;

end.


Көрсетілген бағдарламаны жеңіл түрде жақсартуға болады, егер, келесі өтуден кейін орын ауыстырулар болмаса, тізім сұрыпталған екены анықталады, дегенды ескерсек. Қарастыру бағытын қатар-қатар өзгертіп отырсақ, алгоритм жақсартылады. Бұл жағдайда алгоритм «шейкерлік» алгоритм деп аталады.

Мысалы. Төменде берілген тізбекті іріктеу керек

44 55 12 42 94 18 06 67

Кетсе 2. Көпіршік әдісіне мысалы


I = 1


2

3

4

5

6

7

8

44

06

06

06

06

06

06

06

55

44

12

12

12

12

12

12

12

55

44

18

18

18

18

18

42

12

55

44

42

42

42

42

94

42

18

55

44

44

44

44

18

94

42

42

55

55

55

55

06

18

94

67

67

67

67

67

67

67

67

94

94

94

94

94

 

Бағдарлама 2. Көбікше әдіс В

 PROGRAM BS;

VAR I,J,X,N:INTEGER;

A:ARRAY[0..50] OF INTEGER;

BEGIN


WRITELN('массивтің ұзындығын беріңіз');

READ(N);


WRITELN('массив элементтерін беріңіз');

FOR I:=1 TO N DO READ(A[I]);

FOR I:=2 TO N DO FOR J:=N DOWNTO I DO IF A[J-1]>A[J] THEN BEGIN

X:=A[J-1];

A[J-1]:=A[J];

A[J]:=X


END;

WRITELN('нәтиже:');

FOR I:=1 TO N DO WRITE(A[I],' ')

END.


Бұл әдістің жақсартылған нұсқасы Шейкерлік сұрыптау деп аталады.

Бағдарлама 3. Ауыстыруларды тексеру арқылы айырбастау бойынша сұрыптау.

program Sort_Obmen1;

var  A:array[1..100] of integer;  

N,i,k,x : integer; p:boolean;

begin


write('массив элементтерінің саны');

read(N);

for i:=1 to n do read(A[i]);

k:=n-1; {бірінші сүзгі кезіндегі парлар саны}

p:=true; {логикалық айнымалы p ақиқат, егер алмастырулар

                болса, онда сұрыптауды жалғастыру}

while p do

begin


p:=false;

{Жаңа сүзгінің басталу. Әлі алмастырулар болған жоқ.}

for i:=1 to k do

if A[i]>A[i+1] then

begin

 

x:=A[i]; A[i]:=A[i+1]; A[i+1]:=x;



{элементтердің орындарын ауыстыру}

p:=true; {алмастыру жағдайын есте сақтау}

end;

k:=k-1;



{келесі сүзгі үшін парлар санын азайтамыз}

end;


for i:=1 to n do write(A[i],' '); {реттелген массив}

end.


Сұрыптау алгоритмінің келесі түрлендіруі ең соңғы ауыстыруды есте сақтап айырбастау жасаумен орындалады. Егер келесі сүзгіде соңғы парласа элементтер орындарымен ауыстырылса, A[i] және A[i+1], онда i+1 массив элементі соңында дейін өз орнында қала береді. Бұл информацияны пайдалану бізге келесі i+1 сүзгідегі парлар санын білуімізге мүмкіндік береді.

Бағдарлама 4. Соңғы алмастыру орнын есте сақтау арқылы айырбастау бойынша сұрыптау.

program Sort_Obmen2;

var  A:array[1..100] of integer;  

N,i,k,x,m : integer;

begin


write('массив элементтерінің саны');

read(N);

for i:=1 to n do read(A[i]);

k:=n-1; {бірінші сүзгі кезіндегі парлар саны}

while k>0 do

begin


m:=0;

{бұл сүзгі кезінде ауыстырулар болған жоқ, орын 0 тең}

for i:=1 to k do

if A[i]>A[i+1] then

begin

x:=A[i]; A[i]:=A[i+1]; A[i+1]:=x; {элементтер  орындарын ауыстырамыз} 

m:=i; {және алмастырған орындарды есте сақтаймыз}

end;


k:=m-1; {жұптар саны соңғы ауыстырылған орынға байланысты}

end;


for i:=1 to n do write(A[i],' '); {реттелген массив}

end.


Бақылау сұрақтар

  1. «Көпіршік» әдісінің ерекшелігі неде?

  2. Бұл сұрыптау әдісі қандай классқа жатады?

  3. Бұл әдіс тағы қалай аталады?

  4. Берілген сұрыптау әдісінің ішіне қандай цикл жатады?

  5. Берілген әдіс тиімді болып табылама?

3. Шейкерлік іріктеу (Мойындық іріктеу). (1 сағат)

Дәрістің мақсаты- студенттерді шейкерлік сұрыптау әдісімен және негізгі принциптерімен таныстыру.

Берілген алгоритмнің негізінде келесі позициялар жатады. Қатал берілген қайталанулардан бас тарту керек, сыртқы цикл ішкі циклдың жұмыс барысында ешқандай орын ауыстырулар болмаған жағдайда өзінің жұмысын аяқтау керек.

Бұл алгоритмнің негізгі мағынасы алмастыру бойынша сұрыптауға жатады. Айрымашылығы, алмастыру бойынша сұрыптау тек бір бағыт бойынша жүргізілетіндігін байқадық, ал бұл жағдайда бағыт әрбір рет өзгеріп тұрады. Мойындық сұрыптауда ауыстырулар туралы және соңғы алмастыру жасалған орынды есте сақтап отырады. Базалық алгоритмде екілік сүзгі саны N div 2 –ге тең.



Шейкерлік сұрыптау: ішкі циклдің ішіндегі өтулердің бағыттаррын өзгертіп отыру керек, сөйтіп элементтердің орындарын ауыстыруларынның бағыт бойынша және кері бағыттағы «ассиметриялылығын» компенсациялауға болады.

Біріншіден, егер массив бөлігінде қозғалыстарда орын ауыстырулар болмаса онда массивтің бұл бөлігі сұрыпталған болып есептеледі, сондықтан, оны қарастырудан алып тастауға болады.

Екіншіден, массивтің соңынан басына дейін өткенде минималды элемент бірінші позицияға тұрады, ал максималды элемент тек бір позицияға оң жаққа қарай қозғалады.

Массивтің жұмыс бөлігінің шектері әр итерацияның орын ауыстыруында орнықтырылады. Массив рет бойынша оң жақтан сол жаққа және сол жақтан оң жаққа кезек кезек қарастырылады.

Бұл сұрыптаудың үздік жағдайы — сұрыпталған массив (О(n)), ең жаманы — кері бағытта сұрыпталған массив (O(n²)).

Салыстырулар санының ең кіші мәні Шейкер-сұрыптауында C=N-1. Бұл сұрыпталған массивте тек бір өтуге сәйкес (үздік жағдай)

Шейкер әдісінің бағдарламалық реализациясы:

Бағдарлама 5. Шейкер әдісі А

program sheiker_sort;

(*шейкерлік сұрыптау*)

const N=5;

type item= integer;

var a: array [1 n] of item; i, j, k, L, R: integer; x: item;

begin (*бастапқы массивті беру*)

for i: =1 to N do begin write ('элементтерді еңгізу а [', i, '] = ');

readln (a[i]);

end;

for i:=1 to N do begin write (a[i], ' ');



end;

writeln;

(*шейкерлік сұрыптаудың алгоритмі*)

L: =2; R:=n; k:=n;

repeat

for j:=R downto L do begin

if a [j-l]>a[j] then begin x:=a [j‑1]; a [j‑1]:=a[j];

a[j]:=x; k:=-j

end;

end;


L:=k+1;

for j:=L to R do begin

if a [j-l]>a[j] then begin x:=a [j-l]

a [j-l]:=a[j]; a[j]:=x; k:=j

end;

end;


R:=k‑1; until L>R;

(*сұрыпталған массивті шығару*)

for i:=l to N do

begin write (a[i], ' ');

end;

readln;



end.

Екінші дәрісте берілген тізбекті Шейкер әдісімен сұрыптап көрейік

Кесте 3. Шейкерлік сұрыптауға мысалы.

 L = 2

3

3

4

4

R = 8

8

7

7

4

Dir =

 

 

 

 

44

06

06

06

06

55

44

44

12

12

12

55

12

44

18

42

12

42

18

42

94

42

55

42

44

18

94

18

55

55

06

18

67

67

67

67

67

94

94

94

Шейкер сұрыптау бағдарламасының басқа түрі

Бағдарлама 6. Шейкер әдісі В

 PROGRAM SS;

VAR


J,L,K,R,X,N,I:INTEGER;

A:ARRAY[0..50] OF INTEGER;

BEGIN

WRITELN('массивтің ұзындығын еңгізіңіз’);



READ(N);

WRITELN('массивті еңгізіңіз');

FOR I:=1 TO N DO READ(A[I]);

L:=2;


R:=N;

K:=N;


REPEAT

FOR J:=R DOWNTO L DO IF A[J-1]>A[J] THEN BEGIN

X:=A[J-1];

A[J-1]:=A[J];

A[J]:=X;

K:=J


END;

L:=K+1;


FOR J:=L TO R DO IF A[J-1]>A[J] THEN BEGIN

X:=A[J-1];

A[J-1]:=A[J];

A[J]:=X;


K:=J

END;


R:=K-1

UNTIL L>R;

WRITELN('нәтиже:');

FOR I:=1 TO N DO WRITE(A[I],' ')

END.

Бақылау сұрақтар


  1. Шейкерлік сұрыптау қай әдістің жақсартылған версиясы болып табылады?

  2. Бұл әдістің ең үздік жағдайы болып не табылады?

  3. Неге бұл әдісті шейкерлік деп атаған?

  4. Шейкерлік әдісте сұрыптау неше бағыт бойынша өткізіледі?

4. Тікелей қосу іріктеуі. ( 2 сағат)

Дәрістің мақсаты- студенттерге берілген сқрыптауда қолданылатын негізгі түсініктемелерін беру, оларға әдістің негізін түсіндіру.

Тікелей қосулары бар іріктеу алдында айтылған іріктеулерге ұқсайды.

Ұқсас түрде массивтің бөлігінде жүрістер өткізіледі, және аналогтық түрде оның басында сұрыпталған тізім пайда болады.

Алгоритмді i-ші қадамдағы амалдардан бастап қарастырайық. Алдында айтылғандай, рет бұл уақытқа дейін екі бөлікке бөлінеді: дайын a[0]...a[i] және реттелмеген a[i+1]...a[n].

Келесі, алгоритмнің әр (i+1)-ші қадамында a[i+1] элементін аламызда дайын массивтің керекті орнына қоямыз.


Кезекті элементтің орны оның алдында тұрған элементпен салыстырулар бойынша табылады.
Нәтижеге тәуелді элемент немесе өз орнында қалады немесе олар орындарымен ауысады.

Ағымдағы уақыттағы тізбек. a[0]…a[2] бөлшегі сұрыпталған.

24 23 қосу процесі аяқталды

2 санын сұрыпталған тізімге қосу. Салыстырылатын жұптар белгіленген.

Сонымен, қосулар процессінде біз х элементін массивтің басына қоыямыз, бірақ кейде тқұтатулар орналастырамыз, егер


  1. Х-тан кіші элемент табылса

немесе

  1. Тізімнің басына жетсек.

Бағдарлама 7. Тікелей қосу.

program pr_vkl;

(*сызықтық іздеу бойынша қосуы бар сұрыптау*)

const N=5;

type item= integer;

var a: array [0 n] of item; i, j: integer; x: item;

begin (*бастапқы массивті беру*)

for i:=1 to N do begin write ('элемент еңгізіңіз a [', i, ']=');

readln (a[i])

end;


for i:=1 to N do begin write (a[i], ' ');

end;


writeln;

(*сұрыптау алгоритмі*)

for i:=2 to n do

begin


x:=a[i]; j:=i; a[0]:=x; (*барьер*)

while x
begin

a[j]:=a [j‑1]; j:=j‑1;

end;


a[j]:=x;

{for k:=1 to n do write (a[k], ' ') end; writeln;} end;

(*сұрыпталған массивті шығару*)

for i:=1 to N do

begin

write (a[i], ' '); end;

readln; end.

Таңдауы бар сұрыптау әдісіне ұқсас салыстырулардың және орын ауыстырулардың ортақ және ең жаман саны Theta(n2) жазбасымен бағаланады, қосымша жады бұл жағдайда қолданылмайды.

Алгоритмді кішкене жақсартуға болады. Ішкі циклдің әр қадамында ә шарт тексерілетінін белгілейік. Оларды біріктіруге болады, массивтің басына күзетші элемент қойып. Ол алдын ала массивтің барлық элементтерінен кіші болуы тиіс.

Онда j=0 болғанда a[0] <= x ақиқат болады. Цикл нөльдік элементте тоқтатылады, бұл j>=0 шартының мақсаты болды.

Сонымен, сұрыптау дұрыс түрде өтеді, ал ішкі циклдің ішінде бір салыстыруға аз болады. Ол Theta(n2) рет өткізілген десек, бұл - нақты артықшылық. Бірақ сұрыпталған массив толық болмайды, оның ішінен бірінші элемен шығып кеткендіктен. Сұрыптауды аяқтау үшін бұл санды орнына қайтару керек, содан кейін a[1]...a[n] сұрыпталған реттің ішіне қою керек.

Тікелей қосу әдісінің талдауына оралайық. Дайын тізбек қазірдің өзінде сұрапталған болғандықтан, алгоритм екіге бөлу арқылы іздеу алгоритмімен қолданғандықтан кейін жақсартылады. Бұл әдіс екілік қосу сұрыптауы деп аталады.

Бағдарлама 8. Екілік қосу сұрыптауы

program dv_vkl_sort;

(*Екілік қосу сұрыптауы*)

const N=5;

type item= integer;

var a: array [0 n] of item; i, j, m, L, R: integer; x: item;

begin (*массивтің элементтерін беру*)

for i: – l to N do begin write ('элемментерді беру a [', i, ']= ');

readln (a[i]);

end;


for i:=1 to N do begin write (a[i], ' ');

end;


writeln;

(*екідік қосу сұрыптауының алгоритмі*)

for i:=2 to n do

begin


x:=a[i]; L:=l; R:^i;

while L

begin

m:=(L+R) div 2; if a [m] <=x then L:=m+1 else R:=m;

end;

for j:=i downto R+l do a[j]:=a [j‑1];



a[R]:=x; end;

(* сұрыпталған массивті шығару*)

for i: – l to N do

begin write (a[i], ' ');

end;

readln;


end.


Бақылау сұрақтар

  1. Тікелей қосу сұрыптауы деген не?

  2. Екілік қосу сұрыптауы деген не?

  3. Берілген әдіс «көпіршік » және таңдау әдісінен немен ерекшелінеді?

  4. Кезекті элементті дұрыс орны қай жолмен табылады?

  5. Сұрыптаудың ортақ және ең жаман жағдай қалай бағаланады?

  6. Сұрыптаудағы «Күзетші элемент» деген не?



  1. Шелл сұрыптау әдісі. ( 1 сағат)

Дәрістің мақсаты –студенттерді берілген әдіспен таныстыру және сұрыптаудың негізгі амалдарымен таныстыру.

Бұл әдіс Дональд Л. Шеллмен ұсынылған, орналасқан жері бойынша тұрақсыз сұрыптау болып табылады. Шелл әдісі қосулар әдісінің жақсартылған нұсқасы.

Шелл әдісінің алгоритмі екі негізгі амалдың көп рет қайталанудан тұрады:

бір ереже бойынша массивтің кейбір элементтерін біріктіру

 біріктірілген элементтер арасында әдеттегідей қосу әдісімен сұрыптау

Бірінші кезеңде жеткілікті улкен қадамды кіріс жиынның элементтері топталады. Мысалы, барлық 1000-ші элементтер, яғни топтар құрастырылады:

Топ 1: 1, 1001, 2001, 3001 және т.б.

Топ 2: 2, 1002, 2002, 3002 және т.б.

Топ 3: 3, 1003, 2003, 3003 және т.б.

. . . . . . . . . . . . . . . . . . . . .

Топ 1000: 1000, 2000, 3000 және т.б.

Әр топтың ішінде әдеттегідей қосу сұрыптауы орындалады, бұл топтағы элементтер саны аз болған жағдайда тиімді болады.

Екінші кезеңді топтасу кішірек қадаммен орындалады, мысалы - қалған барлық жүзінші элементтер. Әр топта тағыда әдеттегідей сұрыптау орындалады. Бірінші кезеңнен кейін әр топта жиын бөлікті топталған болады.

Соңғы кезеңде басында топтасы 1 қадаммен орындалады, бұл n өлшемді тек бір жиынды құрастырады, содан кейін – практикалық түрде сұрыпталған жиын іріктіріледі.



Мысалы. Берілген сандар: 15 33 42 07 12 19. Бұл тізбекті іріктеу керек.

3 санына тең қадаммен бөлеміз, бізде 2 элементтен тұратын і топ бар, әрқайссысын жеке жеке сұрыптаймыз:

топ 1: 15 – 07 => 07 – 15 (1 салыстыру, 1 ауыстыру)

топ 2: 33 – 12 => 12 – 33 (1 салыстыру, 1 ауыстыру)

топ 3: 42 – 19 => 19 – 42 (1 салыстыру, 1 ауыстыру)

сандардың жаңа жиыны: 07 15 12 33 19 42

2 санға тең 3 элементтен бөлеміз, олар жеке сұрыпталады:

топ 1: 07 – 12 – 19 => реттелген (2 салыстыру, 0 ауыстыру)

топ 2: 15 – 33 – 42 => реттелген (2 салыстыру, 0 ауыстыру)

сандардың жаңа жиыны: 07 12 19 15 33 42

Соңғы қадамы 1 тең бөлу сандардың керекті жиынын береді; оған 5 салыстырулары бар қосу іріктеуі қолданылады және тек бір орын ауыстыру орындалады, сонымен біз нәтижеге ие боламыз.

Сонымен – 12 салыстыру және 4 ауыстыру, алдында қарастырылған әдістерден жақсырақ емес. Бірақ мұнда екі факторды ескеру керек.

1, 3, 5, 9, 17, 33, . . . (жалпы формула: tk = (2* tk-1) –1 )

1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767 . . . (жалпы формула: tk = (2* tk-1) +1, ал қарапайымы – (2k – 1)).

Бағдарламалық түрде іске асыру (Шелл әдісі бағдарламасының негізгі бөлігі)

for m := 1 to t do {t – топтасудың қадамдарының саны, m – қадамның номірі}

begin

k := h [m]; {берілген массивте қадамның өлшемін таңдау }



for i := k + 1 to n do {қосу сұрыптауы әр топтың ішінде }

begin

temp := a [i]; j := i – k;



while (j > 0) and (temp < a [j]) do

begin

a [j + k] := a [j]; j := j – k;



end;

a [j + k] := temp;



end;

end;

Бағдарлама 9. Шелл әдісі

 PROGRAM SHELLS;

CONST T=4;

H: ARRAY[1..4] OF INTEGER = (15,7,3,1);

VAR


I,J,K,S,X,N,M:INTEGER;

A:ARRAY[-16..50] OF INTEGER;

BEGIN

WRITELN('массивтің ұзындығын беріңіз');



READ(N);

WRITELN('массивтің элементтерін еңгізіңіз');

FOR I:=1 TO N DO READ(A[I]);

FOR M:=1 TO T DO BEGIN

K:=H[M];

S:=-K;


FOR I:=K+1 TO N DO BEGIN

X:=A[I];


J:=I-K;

IF S=0 THEN S:=-K;

INC(S);

A[S]:=X;


WHILE XA[J+K]:=A[J];

J:=J-K

END;


A[J+K]:=X

END;


END;

WRITELN('нәтиже:');

FOR I:=1 TO N DO WRITE(A[I],' ')

END.


Шелл әдісінің күрделілігі O(n1,2) сәйкестікпен бағаланады,бұл қарапайым әдістерге қарағанда әлде қайда жақсы.

Бақылау сұрақтар

  1. Шелл әдісі неде негізделеді?

  2. Бұл әдіс өзінің атын неден алды?

  3. Берілген әдіс сқрыптау әдістерінің қай классына жатады?

  4. Берілген әдістің күрделілігі қалай бағаланады?

  5. Шелл әдісінің тиімділігі неге тәуелді?




  1. Достарыңызбен бөлісу:
1   ...   6   7   8   9   10   11   12   13   14




©engime.org 2024
әкімшілігінің қараңыз

    Басты бет