«Көпіршік» тәсілі

Осы тәсілді пайдаланған кезде (n-1) – дің ең үлкен өтулері керек. Кестенің бірінші өтуі кезінде бірінші және екінші жазбаның К1 және К2 кілттері салыстырылады, егер де олардың арасындағы тәртіп бұзылса, онда R1және R2 жазбалары орындарын ауыстырады. Содан кейін осы процесс R2 және R3, R3 және R4 т.с.с. үшін қайталанады. Осы тәсіл аз кілттері бар жазбаларды қозғалтуға және білінуге мәжбүр етеді. Бірінші өтүден кейін ең көп мәні бар жазбадағы кілт кестенің n-ші позициясында тұрады. Әрбір келесі өтулер кезінде ең көп мәндері бар келесі жазбалардағы кілттер n-1, n-2, …,2 позицияларында орналасады, нәтижесінде сұрыпталған кесте шығады. Әрбір өтулерден кейін осы өтулер кезінде ауыстырулар болда ма, жоқ па деген тексеруді да істеуі мүмкін. Егер де ауыстырулар жоқ болса, онда ол кесте сұрыпталғаны екені және де одан арғы өтулерді қажет етпейтінін білдіреді. Сонымен қатар, соңғы ауыстырудың индексін есте сақтауға болады. Бұл келесі қадамдағы қарайтын қосалқы кестені кішірейтуге мүмкіндік береді. «Көпіршік» тәсілімен сұрыптағандағы сипаттамасы ең болмағанда n(n-1)/2 салыстыруларын және n(n-1)/2 ауыстыруларын құрайды. Салыстырудың және ауыстырудың орташа саны n**2 рет.

Паскаль және Си тілдеріндегі «Көпіршік» тәсілін іске асыратын процедура төменде келтірілген:

Паскаль                          Си

Type  typedef
Rec=Record  struct{
f1 : char;                                               char f1;
f2 : integer;  int f2;
f3 : integer int f3; } rec;
End;
Table = Array[1..100] Of Rec; rec[100] table;
procedure bubble(var T:Table;  void bubble(table *t,int n);
n:integer); /* t — кесте */
{ T — кесте; n – оның өлшемі }                                /* n – жазба өлшемі */
{ f3 ауданы бойынша сұрыптау}        /* f3 ауданы бойынша сұрыптау */
{
var  int i,j,pr;
i:integer;  rec el;
temp:Rec;                                    /* f3 ауданы бойынша сұрыптау */
switch:boolean; do{
begin  pr=0;
repeat  for( j=0;j<n;j++)
switch:=false; {
for i:=1 to n-1 do if(*t[j].f3>*t[j+1].f3)
if T[i].f3>T[i+1].f3 then {
begin  el=*t[j];
switch:=true;  *t[j]=*t[j+1];
temp:=T[i]; *t[j+1] = el;
T[i]:=T[i+1];  pr=1;
T[i+1]:=temp }
end  }
until not(switch)  }while(pr==1);
end }

Бұл тәсіл ауыстыру тәсілімен сұрыптауды пайдаланады. Ол салыстыру операцияларының циклында орындалуында және көршілес тұрған элементтерін ауыстыруға қажеттігіне негізделген. Оның аталуы сумен толтырылған резервуардағы көпіршіктердің қозғалу кезіндегі процесске ұқсас болғандықтан олай аталды. Әрбір көпіршік өз жиегін табады. Төменде көпіршік тәсілімен сұрыптаудың ең қарапайым программаның формасы көрсетліген:

{Көпіршік тәсілімен сұрыптаудың басталуы}

procedure Bubble(var item: DataArray; count:integer);
var
i,j: integer;
x: DataItem;
begin
for i := 2 to count do
begin
for j := count downto i do
if item[j-1]>item[j] then
begin
x := item[j-1];
item[j-1] := item[j];
item[j] := x;
end;
end;
end; { Көпіршік тәсілімен сұрыптаудың аяқталуы }

Бұл мысалда берілген «item» «Dataitem» элементінің массиві болып табылады. Ол сұрыпталады да, ал берілген «count» массивінде элементтердің саны бар. Көпіршік тәсілімен сұрыптаудың екі циклі бар. Массив элементінің саны «count» айнымалымен берілгендіктен, сыртқы цикл count массивінің қаралуын 1 рет ғана шақырады. Бұл процедура аяқталғаннан кейін әрбір элементтің өз позициясында тапқанын қамтамасыз етеді. Ішкі цикл салыстыру және ауыстыру операцияның шындығымен орындалатынына негізделген. Көпіршік тәсілімен сұрыптаудың осы версиясы символдық массивтегі элементтердің мәндерін өсу реті бойынша сұрыптай алады. Мысалы, келесі қысқа программа «test.dat» дисктік файлынан оқитын жолды сұрыптайды:

program SortDriver;
{бұл программа «test.dat» дисктік файлынан 80 немесе одан да аз символдарын сұрыптайды да, нәтижені экранға шығарады }

type
DataItem = char;
DataArray = array [1..80] of char;
var
test: DataArray;
t, t2: integer;
testfile: file of char;
{ Көпіршік тәсілімен сұрыптау}
procedure Bubble(var item: DataArray; count:integer);
var
i,j: integer;
x: DataItem;
begin
for i := 2 to count do
begin
for j := count downto i do
if item[j-1]>item[j] then
begin
x := item[j-1];
item[j-1] := item[j];
item[j] := x;
end;
end;
end;
begin
Assign(testfile, ‘test.dat’);
Reset(testfile);
t := 1;

{ сұрыптауға кететін символдарды оқу}

while not Eof(testfile) do begin
read(testfile, test[t]);
t := t+1;
end;
t := t-2; {есептелген элементтердің санын дұрыстау }
Bubble(test, t); { массивті сұрыптау}
{ сұрыпталған сиволдық массивтің шығарылуы }
for t2 := 1 to t do write(test[t2]);
WriteLn;
end.

Көпіршік тәсілімен сұрыптауының бір ерекшелігі бар: массивтің соңындағы өз орнында тұрмаған элемент (мысалы, «dcab» массивіндегі «а» элементі) бір өту арқылы өз орнына жетеді, ал массивтің басында орналасқан элемент (мысалы, «d» элементі), өз орнына өте баяу жетеді. Барлық қарауларын бір бағытта істеу міндетті емес. Оның орнына әрбір келесі қарауын қарама-қарсы бағытта істеуге болады. Бұл жағдайа өз орнынан қатты алыстап кеткен элементтер тез арада өз орнына жылжиды.