| ZER DAKIDAN: Arrayekin lan egiteko hainbat algoritmo ezagutzen dut. ZER IKASIKO DUDAN: Array desordenatu bat ordenatzen edo sailkatzen ikasiko dut orain. |
Zenbaki osoen array bat irudikatzen dute dantzariek, aukeraketa algoritmoa aplikatuz arraya sailkatuko dute
Demagun array dimentsiobakar bat dugula (bektore bat) eta bere elementuak zenbaki errealak direla, 0-tik 9-ra bitarteko alde osoa eta 0-tik 9-ra dezimal bakarra duten zenbaki errealak alegia.
Sailkatzeko algoritmo desberdinetatik aukeraketa algoritmoa azalduko dugu ulerterraza delako, une bakoitzean zenbakirik txikiena aukeratuko dugu. Hauxe litzateke algoritmoaren irudia:
Eta hauxe da algoritmoaren azalpena...
Goiko eskeman ikus daitekeenez k kontagailuaren laugarren iterazioan gaude, ordurako array sailkatuaren lehen hiru elementuak zehaztu dira, eta iterazio honetan aurkituko den minimoa gelaxka ilunean kokatuko dugu (k=4 posizioan alegia). Laugarren iterazioari dagokion minimoa bilatzeko, arrayaren sailkatu/ordenatu gabeko aldean begiratu beharra dago eta horretarako j kontagailua erabiliko da.
| Zer dakigun k iterazioan: sailkatzeko hurrengo elementua non kokatuko den, arrayaren k posizioan. Zer ez dakigun k iterazioan: arrayaren bigarren zatiko elementuen artean zein da sailkatzeko hurrengo elementua (bai badakigu balio minimoa duen elementua dela, baina ez zein den bere posizioa). |
k=4 iterazioari dagokion minimoa zehazteko Min eta Pos aldagai laguntzaileen bitartez egiten da. Hasiera batean Min aldagaian sailkatu/ordenatu gabeko tartearen lehen elementuaren balioa gordetzen da, hots, Min aldagaian A[k] elementuaren balioa gordetzen da eta Pos aldagaian elementu horri dagokion k posizioa. Hasieraketak egin ondoren, barneko FOR-DO bitartez sailkatu/ordenatu gabeko aldea aztertzen da elementurik txikiena zehaztuz (bere balioa eta bere posizioa zehaztuz). Laugarren iterazioan minimoa zein den jakitean, array sailkatuan dagokion tokira (k=4 posiziora) eraman behar da, horregatik k eta Pos indizedun elementuak elkar trukatu egin behar dira.
Hona hemen array bat sailkatzen duen iturburu-programa:
/* 11a-ArrayBatSailkatzea: Zenbaki errealean array bat auzaz bete
ondoren, txikitik handira sailkatu. */
// Zenbaki errealen array bat auzazko datuz bete ondoren, arrayaren elementuak
// ordenatu balio txikienetik balio handienera "aukeraketa" algoritmoa erabiliz.
// Aukeraketaren algoritoaren funtsa da elementurik txikiena aukeratzea iterazio
// bakoitzean. Iterazio jakin batean arrayaren aurreko zatia ordenaturik dago
// arrayaren bukaerako zatia desordenaturik dago. Desordenatua den bigarren zati
// honetan "aukeratu" behar da hurrengo elementua zati ordenatuan. Sailkatzea
// balio txikienetik balio handienera bada "aukeratu" aditzaren esanahia da
// minimoaren posizioa zehaztu. Sailkatzea balio handienetik balio txikienera
// bada, orduan "aukeratu" aditzaren esanahia da maximoaren posizioa zehaztu.
#include <stdio.h>
#include <stdlib.h> // srand() eta rand() funtzioetarako
#include <time.h> // time() funtziorako
#define LUZERAMAX 8
typedef float tafZerrenda[LUZERAMAX]; // gehienez 9 zenbaki gordetzeko arrayak
float fMoldatu(float fDatua);
void ArrayaBete(tafZerrenda afBekt, int *iLuzera);
void ArrayaIkusi(const tafZerrenda afBekt, int iLuzera);
void AukeraketazOrdenatu(tafZerrenda afBekt, int iLuzera);
int main()
{
tafZerrenda afBekt;
int iLuzera;
ArrayaBete(afBekt, &iLuzera);
printf("Ordenatu baino lehen ");
ArrayaIkusi(afBekt, iLuzera);
printf("----------------------------------------------------------------\n");
AukeraketazOrdenatu(afBekt, iLuzera);
printf("----------------------------------------------------------------\n");
printf("Ordenaturik, ");
ArrayaIkusi(afBekt, iLuzera);
return 0;
}
// Zenbaki erreal bat moldatu:
// Alde osorik ez duen zenbaki erreal bat hartu eta alde
// osoan digitu bakarra eta dezimal bakarra duen zenbaki
// erreala itzultzen duen funtzioa: 0.12345 ---> 1.2
float fMoldatu(float fDatua)
{
fDatua = fDatua * 100;
fDatua = (int)fDatua;
return fDatua / 10;
}
// Arraya ausazko balioekin bete:
// Lehenengo parametroa array bat delako eta irteerakoa
// delako erreferentziaz pasatzen da. iLuzera luzera
// erreferentziaz ere balioa prozeduran hartzen duelako
void ArrayaBete(tafZerrenda afBekt, int *iLuzera)
{
srand(time(NULL));
*iLuzera = rand() % LUZERAMAX + 1; // gehienez 9 elementu, indizeak 0-tik 8-ra
if (*iLuzera < 4)
*iLuzera = 4; // gutxienez 4 elementu, indizeak 0-tik 3-ra
printf("Arrayan %d datu gordetzen...\n", *iLuzera);
for (int i = 0; i < *iLuzera; i++)
{
afBekt[i] = (float)rand() / RAND_MAX;
printf("\n%d. auzaz: afBekt[i]=%f", i, afBekt[i]);
afBekt[i] = fMoldatu(afBekt[i]); // 0.0 eta 9.9 artekoak
printf(" moldatuta: afBekt[i]=%.3f", afBekt[i]);
}
printf("\n\n");
}
// Arrayaren edukia pantailaratu:
// Nahiz eta parametro biak sarrerakoak izan, lehenengoa
// array bat delako erreferentziaz pasatzen da const marka
// gehituz aldaketak ekiditeko. Bigarrena berriz balioz
void ArrayaIkusi(const tafZerrenda afBekt, int iLuzera)
{
printf("Arrayaren edukia:\n");
for (int i = 0; i < iLuzera; i++)
{
printf("%8.1f", afBekt[i]);
}
printf("\n");
}
// Arraya aukeraketaz ordenatu:
// Parametro bat irteerakoa den bitartean bestea sarrerakoa
// da. Horregatik, aldatuko den afBekt arraya erreferentziaz
// pasatzen da, baina aldatuko ez den iLuzera luzera logikoari
// dagokion osoa balioz pasarazaten da
void AukeraketazOrdenatu(tafZerrenda afBekt, int iLuzera)
{
int k, j;
int iPos;
float fMin;
for (k = 0; k < iLuzera - 1; k++) // kanpoko begizta, minimoa dagokion posizioan kokatzeko
{
fMin = afBekt[k];
iPos = k;
for (j = k + 1; j < iLuzera; j++) // barruko begizta, minimoa non dagoen zehazteko
{
if (fMin > afBekt[j])
{
fMin = afBekt[j];
iPos = j;
}
}
// bi elementuak trukatu
afBekt[iPos] = afBekt[k];
afBekt[k] = fMin;
// iterazio bakoitza erakutsi
printf("%d. iterazioan, ", k);
ArrayaIkusi(afBekt, iLuzera);
}
printf("%d. iterazioa soberan, arraya sailkaturik dagoelako\n", k);
}
Gauza bera egin daiteke erregistroen bektore batekin. Ikus dezagun adibidez ondoko erregistroan oinarritutako bektore bat nola sailkatzen den bi eremuen informazioaren arabera:
...
#define MAX_IKASLEAK 12
#define MAX_STR49 50
typedef char tsKate49[MAX_STR49]; // ikaslearen izena gordetzeko 49 karaktere gehi null mugatzailea
typedef struct
{
tsKate49 sNor;
int iDeialdia;
float fKalifikazioa;
} trdIkasle;
typedef trdIkasle tardIkasleak[MAX_IKASLEAK];
...
Hona hemen erregistroen array bat sailkatzen bi eremuen arabera. Sailkatze nagusia iDeialdia eremuaren araberakoa da, eta deialdi berdineko elementuak sNor eremuaren arabera ordenatuko dira:
/* 11b-SailkatzeAurreratua: Erregistroen array bat sailkatu bi
eremuko informazioa arabera. */
// Arrayaren hasierako informazioa desordenaturik dago eta ordenatu
// behar da, lehenik deialdien arabera eta ondoren abizenen arabera.
#include <stdio.h>
#include <string.h> // strcmp() funtziorako
#define MAX_IKASLEAK 12
#define MAX_STR49 50
typedef char tsKate49[MAX_STR49]; // ikaslearen izena gordetzeko 49 karaktere gehi null mugatzailea
typedef struct
{
tsKate49 sNor;
int iDeialdia;
float fKalifikazioa;
} trdIkasle;
typedef trdIkasle tardIkasleak[MAX_IKASLEAK];
void ArrayaBete(tardIkasleak ardHasierakoak, int iLuzera);
void DatuakIkusi(const tardIkasleak ardIkasleak, int iLuzera);
void ArrayaSailkatu(tardIkasleak ardHasierakoak, int iLuzera);
// ikasleen izenak, deialdiak eta notak array konstanteetan
const tsKate49 asIZENAK[MAX_IKASLEAK] =
{
"EGIGUREN MARKINEZ, IRUNE", // 0
"GARTZIA DE ALZA GIL, KATALIN", // 1
"HERRANZ MARTINEZ, REBECA", // 2
"CANO RUIZ DE HEREDIA, JULIAN", // 3
"IRAGORRI COTANO, MARTIN", // 4
"FERNANDEZ FEITO, FELIX", // 5
"DIAZ DE ULZURRUN, ROY, LEONOR", // 6
"AGIRRE ROMERO, UNAI", // 7
"ERKIAGA ANDONEGI, IKER", // 8
"BIKARREGI IGLESIAS, JULEN", // 9
"ANGULEMA CARAZO, JON ANDER", // 10
"CORRAL EGIA, JOSEBA ANDONI" // 11
};
const int aiDeialdiaK[MAX_IKASLEAK] = {3, 1, 2, 2, 1, 3, 1, 2, 3, 2, 3, 1};
const float afKALIFIKAZIOAK[MAX_IKASLEAK] = {4.6, 3.2, 5.7, 4.8, 5.1, 6.1, 7.3, 7.6, 2.8, 9.2, 2.9, 8.5};
int main()
{
tardIkasleak ardIkasleak;
int iLuzera;
iLuzera = MAX_IKASLEAK;
ArrayaBete(ardIkasleak, iLuzera);
printf("\n---Arraya sailkatu aurretik-----------------------------------------\n");
DatuakIkusi(ardIkasleak, iLuzera);
ArrayaSailkatu(ardIkasleak, iLuzera);
printf("\n===Array ordenatuaren edukia========================================\n");
DatuakIkusi(ardIkasleak, iLuzera);
return 0;
}
// hasierako arraya bete ikasleen datuekin
void ArrayaBete(tardIkasleak ardIkasleak, int iLuzera)
{
trdIkasle rdIkasleBat;
int k;
for (k = 0; k < iLuzera; k++)
{
strcpy(rdIkasleBat.sNor, asIZENAK[k]);
//printf("\nasIZENAK[k]=%s| rdIkasleBat.sNor=%s|", asIZENAK[k], rdIkasleBat.sNor);
rdIkasleBat.iDeialdia = aiDeialdiaK[k];
rdIkasleBat.fKalifikazioa = afKALIFIKAZIOAK[k];
ardIkasleak[k] = rdIkasleBat;
}
}
// arrayaren edukia pantailaratu
void DatuakIkusi(const tardIkasleak ardIkasleak, int iLuzera)
{
for (int k = 0; k < iLuzera; k++)
{
printf("%4d. ikaslea: %-35s %5d %8.1f\n", k, ardIkasleak[k].sNor,
ardIkasleak[k].iDeialdia,
ardIkasleak[k].fKalifikazioa);
}
}
void ArrayaSailkatu(tardIkasleak ardIkasleak, int iLuzera)
{
//trdIkasle rdIkasleBat;
int k, j;
int iPosMin;
trdIkasle rdMin;
for (k = 0; k < iLuzera; k++) // minimoa kokatzeko posizioa k izango da
{
rdMin = ardIkasleak[k];
//printf("\nrdMin.sNor=%s|\nrdMin.iDeialdia=%d rdMin.fKalifikazioa=%.2f\n", rdMin.sNor, rdMin.iDeialdia, rdMin.fKalifikazioa);
iPosMin = k;
for (j = k+1; j < iLuzera; j++) // ordenatu gabekoen artean minimoa non dagoen zehaztu
{
if (
(rdMin.iDeialdia > ardIkasleak[j].iDeialdia) ||
(
(rdMin.iDeialdia == ardIkasleak[j].iDeialdia) && // rdMin.iDeialdia berdina denean eta...
(strcmp(rdMin.sNor, ardIkasleak[j].sNor) > 0) // rdMin.sNor handiagoa denean...
)
)
{
rdMin = ardIkasleak[j];
iPosMin = j;
}
}
ardIkasleak[iPosMin] = ardIkasleak[k]; // trukatu, tokiz aldatuz
ardIkasleak[k] = rdMin;
}
}


iruzkinik ez:
Argitaratu iruzkina