| ZER DAKIDAN: Arrayekin lan egiteko hainbat algoritmo ezagutzen dut. ZER IKASIKO DUDAN: Orain ikasiko dut elementu berri bat nola sartu arrayaren posizio jakin batean. Ondoren, elementu batzuk arrayan txertatzeko algoritmoak ikasiko ditut. |
Irudian zenbaki errealen afNotak array bat daukagu, bere luzera efektiboa iLuzera aldagaiak adierazten du eta 4 balio du. Irudian ikusten da ere afNotak array hori bete-beterik ez dagoela. Demagun 66.6 balioa txertatu nahi dugulua arrayaren 2 posizioan.
Balio berria arrayan gorde aurretik, tokia egin behar zaio for agindu baten bitartez, eta tokia egina dagoenean balio berria txertatuko da eta, noski, iLuzera aldagaia inkrementatu beharko da.
algoritmo bera bi lengoaietan ematen den: C eta Pascal
Programa nagusiak lau parametro pasatzen dizkio funtzioari, lehenengo biak sarrera/irteerakoak eta azken biak sarrerakoak. Irudiko adibidean for kontrol-egiturari esker hiru iterazi emango dira adibide honetan:
- iterazioan: iIndizea=4 eta libre dagoen afNotak[5] posizioan afNotak[5] balioa kopiatzen delako 56.8 datua bikoiztuta geratzen da
- iterazioan: iIndizea=3 eta bikoiztuta dagoen afNotak[4]posizioko balioa zapaldurik suertatzen da afNotak[3] balioa bere gainean kopiatuz, horregatik 52.9 datua bikoiztuta geratzen da
- iterazioan: iIndizea=2 eta bikoiztuta dagoen afNotak[3]posizioko balioa zapaldurik suertatzen da afNotak[2] balioa bere gainean kopiatuz, horregatik 17.1 datua bikoiztuta geratzen da
Irudiaren adibidean 3. iterazioarekin bukatzen da prozesu errepikakorra, hots, txertaketa burutzeko prestakizunak egin dira baina oraindik txertaketa egin gabe dago. Txertaketa gauzatzeko ondoko bi hauek egin behar dira:
- Eskatzen zen afNotak[3] posizioan 66.6 balioa gorde
- Luzera efektiboa aldatu denez iLuzera=5 jarri behar da (bigarren parametroa irteerakoa izatearen arrazoia hauxe da)
Adibidez, tokia egin eta iNon posizioan fElementua txertatu:
// -------------- Txertaketa edo Tartekaketa ---------------
// afNotak: sarrera/irteerako parametroa, zenbaki errealen
// array bat da
// iLuzera: sarrera/irteerako parametroa, arrayaren luzera
// logikoa adierazten du (irtetean bat gehiago)
// fElementua: sarrerako parametroa, arrayan txertatu behar
// den elementu berriaren balioa
// iNon: sarrerako parametroa, txertatu behar den elementu
// berriaren posizioa adierazten du
void Tartekaketa(tafZerrenda afNotak,
int *iLuzera,
float fElementua,
int iNon)
{
for (int iIndizea = *iLuzera; iIndizea >= iNon; iIndizea--)
{
afNotak[iIndizea + 1] = afNotak[iIndizea];
}
afNotak[iNon] = fElementua;
(*iLuzera)++;
}
Elementu bakar bat txertatzeaz gain, array baten elementu guztiak banan-banan txerta daitezke array ordenatu bat prestatzeko, ikusi Ariketa 60 | Mediana eta media adibidea.
Array batean elementu berri bat txertatzeko algoritmoa ulertuz gero, erraza da ulertzea array batean elementu bakar bat nola kentzen den (ikusi 9. jarduera | Ezabaketa array batean irudia eta azalpena).
Eta arrayan elementu bat baino gehiago txertatu behar baditugu? Arrayan elementu bat baino gehiago txertatu behar baditugu bi aukera ditugu:
- Goiko algoritmoa hainbat aldiz errepikatzea (ikusi 10b-Txertaketa-HainbatElementu.cbp programa)
- Array laguntzaile bat erabiltzea. Zenbat elementu berri eta non sartuko diren teklatuz emaniko datuak ditugula array berria lortzen da 10c-Txertaketa-ArrayLaguntzailez.cbp programan
Ezaguna den iNon posizioko elementua arrayan sartu. Arraya auzaz bete ondoren, txertatuko den elementuaren fElementua balioa eta iNon posizioa ematen dira teklatuz. Arraya beterik ez dagoela frogatu ondoren, elementu berria txertatzen da Txertaketa() delako funtzioan, for agindu bati esker elementu berriari tokia egiten zaio arrayan eta jarraian fElementua esleitu egiten da iNon posizioan. Argi dago, arrayaren iLuzera luzera efektiboa inkrementatu beharko dela unitate batean.
/* 10a-Txertaketa-ElementuBakarra: Txertaketaren algoritmoa elementu bakar bati aplikatuta. */
// Arraya auzaz bete ondoren, txertatuko den elementuaren balioa eta posizioa ematen
// dira teklatuz. Arraya beterik ez dagoela frogatu ondoren, elementu berria txertatzen
// da Txertaketa() delako funtzioan, for bati esker elementu berriari tokia egiten zaio
// arrayan eta jarraian esleitu egiten da iNon posizioan. Argi dago, arrayaren iLuzera
// luzera efektiboa inkrementatu beharko dela unitate batean.
#include <stdio.h>
#include <stdlib.h> // rand() eta srand() funtzioetarako
#include <time.h> // time() funtzioarako
#define BEHEMUGA 0
#define GOIMUGA 19
typedef float tafZerrenda[GOIMUGA]; // gehienez 20 zenbakiren arrayak, indizeak 0-tik 19-ra
void ArrayaBete(tafZerrenda afNotak, int *iLuzera);
void ArrayaIkusi(const tafZerrenda afNotak, int iLuzera);
void Tartekaketa(tafZerrenda afNotak,
int *iLuzera,
float fElementua,
int iNon);
int main()
{
tafZerrenda afNotak;
int iLuzera, iNon;
float fElementua;
srand(time(NULL));
ArrayaBete(afNotak, &iLuzera);
ArrayaIkusi(afNotak, iLuzera);
if (iLuzera < GOIMUGA)
{
do
{
printf("Eman zenbaki berriaren balioa (0.00 eta 9.99 artekoa): ");
scanf("%f", &fElementua);
} while (fElementua < 0.0 || fElementua > 9.99);
do
{
printf("Zenbaki berriaren posizioa arrayan (%d eta %d artekoa): ", BEHEMUGA, iLuzera+1);
scanf("%d", &iNon);
} while (iNon < BEHEMUGA || iNon > iLuzera+1);
Tartekaketa(afNotak, &iLuzera, fElementua, iNon);
ArrayaIkusi(afNotak, iLuzera);
}
else
printf("Arraya beterik dago, ezin da elementu berririk txertatu.\n");
return 0;
}
// ArrayaBete funtzioa
void ArrayaBete(tafZerrenda afNotak, int *iLuzera)
{
*iLuzera = rand() % GOIMUGA + 1; // 0 eta 19 arteko balioak
printf("Arrayan %d datu gordetzen...\n", *iLuzera + 1);
for (int iIndizea = BEHEMUGA; iIndizea <= *iLuzera; iIndizea++)
{
afNotak[iIndizea] = 10.0 * rand() / RAND_MAX; // 0.00 eta 9.99 arteko balioak
}
}
// ArrayaIkusi funtzioa
void ArrayaIkusi(const tafZerrenda afNotak, int iLuzera)
{
printf("Arrayaren edukia:\n");
for (int iIndizea = BEHEMUGA; iIndizea <= iLuzera; iIndizea++)
{
printf("%2d. nota = %.3f\n", iIndizea, afNotak[iIndizea]);
}
printf("\n");
}
// -------------- Txertaketa edo Tartekaketa ---------------
// afNotak: sarrera/irteerako parametroa, zenbaki errealen
// array bat da
// iLuzera: sarrera/irteerako parametroa, arrayaren luzera
// logikoa adierazten du (irtetean bat gehiago)
// fElementua: sarrerako parametroa, arrayan txertatu behar
// den elementu berriaren balioa
// iNon: sarrerako parametroa, txertatu behar den elementu
// berriaren posizioa adierazten du
void Tartekaketa(tafZerrenda afNotak,
int *iLuzera,
float fElementua,
int iNon)
{
for (int iIndizea = *iLuzera; iIndizea >= iNon; iIndizea--)
{
afNotak[iIndizea + 1] = afNotak[iIndizea];
}
afNotak[iNon] = fElementua;
(*iLuzera)++;
}
Arraya auzaz bete ondoren elementu berri sorta bat sartuko dugu arrayaren iNondik posizio jakin batetik aurrera. Jakin beharra dago ere zenbatekoa den elementu berrien iZenbat kopurua.
HainbatTartekaketa() funtzioan iZenbat iterazio egiten dira eta iterazio bakoitzean dagokion elementu berriaren balioa irakurtzen da teklatutik. Txertaketaren lana BatTartekakatu() funtzioak betetzen du eta iLuzera aldagaia unitate batez inkrementatzen du.
/* 10b-Txertaketa-HainbatElementu: Txertaketaren algoritmoa hainbat elementui aplikatuta. */
// Arraya auzaz bete ondoren elementu berri sorta bat sartuko dugu arrayaren
// iNondik posizio jakin batetik aurrera. Jakin beharra dago ere zenbatekoa
// den elementu berrien iZenbat kopurua.
// HainbatTartekaketa() funtzioan iZenbat iterazio egiten dira eta iterazio
// bakoitzean dagokion elementu berriaren balioa irakurtzen da teklatutik.
// Txertaketaren lana BatTartekakatu() funtzioak betetzen du eta iLuzera
// aldagaia unitate batez inkrementatzen du.
#include <stdio.h>
#include <stdlib.h> // rand() eta srand() funtzioetarako
#include <time.h> // time() funtzioarako
#define BEHEMUGA 0
#define GOIMUGA 19
typedef float tafZerrenda[GOIMUGA]; // gehienez 20 zenbakiren arrayak, indizeak 0-tik 19-ra
void ArrayaBete(tafZerrenda afNotak, int *iLuzera);
void ArrayaIkusi(const tafZerrenda afNotak, int iLuzera);
void BatTartekakatu(tafZerrenda afNotak,
int *iLuzera,
float fElementua,
int iNon);
void HainbatTartekaketa(tafZerrenda afNotak,
int *iLuzera,
int iNondik,
int iZenbat);
int main()
{
tafZerrenda afNotak;
int iLuzera, iZenbat, iNondik;
srand(time(NULL));
ArrayaBete(afNotak, &iLuzera);
ArrayaIkusi(afNotak, iLuzera);
if (iLuzera < GOIMUGA)
{
do
{
printf("Eman zenbat nota berri txertatuko diren (gehienez %d nota): ", GOIMUGA - iLuzera);
scanf("%d", &iZenbat);
if (iZenbat > GOIMUGA - iLuzera)
printf("Arrayan gehienez %d elementu berri txerta daitezke.\n", GOIMUGA - iLuzera);
} while (iZenbat < 1 || iZenbat > GOIMUGA - iLuzera);
do
{
printf("Zenbaki berrien sortaren hasierako posizioa arrayan: ");
scanf("%d", &iNondik);
if (iNondik < BEHEMUGA || iNondik > iLuzera + 1)
printf("Hasierako posizioa %d eta %d artekoa izan dadila.\n", BEHEMUGA, iLuzera + 1);
} while (iNondik < BEHEMUGA || iNondik > iLuzera + 1);
HainbatTartekaketa(afNotak, &iLuzera, iNondik, iZenbat);
ArrayaIkusi(afNotak, iLuzera);
}
else
printf("Arraya beterik dago, ezin da elementu berririk txertatu.\n");
return 0;
}
// ArrayaBete() funtzioa
void ArrayaBete(tafZerrenda afNotak, int *iLuzera)
{
*iLuzera = rand() % GOIMUGA + 1; // 0 eta 19 arteko balioak
printf("Arrayan %d datu gordetzen...\n", *iLuzera + 1);
for (int iIndizea = BEHEMUGA; iIndizea <= *iLuzera; iIndizea++)
{
afNotak[iIndizea] = 10.0 * rand() / RAND_MAX; // 0.00 eta 9.99 arteko balioak
}
}
// ArrayaIkusi() funtzioa
void ArrayaIkusi(const tafZerrenda afNotak, int iLuzera)
{
printf("Arrayaren edukia:\n");
for (int iIndizea = BEHEMUGA; iIndizea <= iLuzera; iIndizea++)
{
printf("%9d. nota = %.3f\n", iIndizea, afNotak[iIndizea]);
}
printf("\n");
}
// BatTartekakatu() funtzioa
void BatTartekakatu(tafZerrenda afNotak,
int *iLuzera,
float fElementua,
int iNon)
{
for (int iIndizea = *iLuzera; iIndizea >= iNon; iIndizea--) {
afNotak[iIndizea + 1] = afNotak[iIndizea];
}
afNotak[iNon] = fElementua;
(*iLuzera)++;
}
// HainbatTartekaketa() funtzioa
void HainbatTartekaketa(tafZerrenda afNotak,
int *iLuzera,
int iNondik,
int iZenbat)
{
int iNon = iNondik;
float fElementuBerria;
for (int iIndizea = 1; iIndizea <= iZenbat; iIndizea++)
{
printf("Eman sortaren %d. zenbaki berriaren balioa: ", iIndizea);
scanf("%f", &fElementuBerria);
BatTartekakatu(afNotak, iLuzera, fElementuBerria, iNon);
iNon++;
}
}
Arraya auzaz bete ondoren elementu berri sorta bat sartuko dugu arrayaren iNondik posizio jakin batetik aurrera. Jakin beharra dago ere zenbatekoa den elementu berrien iZenbat kopurua.
HainbatTartekaketa() funtzioan afLaguntzailea[] arraya elikatuko da hiru zatiekin:
- afNotaka[] arrayaren BEHEMUGA-iNondik zatia
- Sorta berriaren iZenbat zatia
- afNotaka[] arrayaren iNondik-iLuzera zatia
Azkenean, afLaguntzailea[] arrayaren edukia afNotaka[] arrayan gordeko da eta iLuzera zaharraren balioa ordezkatuko da iLuzeraLagunt baliogatik.
/* /* 10c-Txertaketa-ArrayLaguntzailez: Txertaketaren algoritmoa hainbat elementui aplikatuta. */
// Arraya auzaz bete ondoren elementu berri sorta bat sartuko dugu arrayaren
// iNondik posizio jakin batetik aurrera. Jakin beharra dago ere zenbatekoa
// den elementu berrien iZenbat kopurua.
// HainbatTartekaketa() funtzioan afLaguntzailea[] arraya elikatuko da hiru
// zatiekin:
// 1. BEHEMUGA-iNondik zatia
// 2. Sorta berriaren iZenbat zatia
// 3. iNondik-iLuzera zatia
// Azkenean, afLaguntzailea[] arrayaren edukia afNotak[] arrayan gordeko da
// eta iLuzera zaharraren balioa ordezkatuko da iLuzeraLagun baliogatik.
#include <stdio.h>
#include <stdlib.h> // rand() eta srand() funtzioetarako
#include <time.h> // time() funtzioarako
#define BEHEMUGA 0
#define GOIMUGA 19
typedef float tafZerrenda[GOIMUGA]; // gehienez 20 zenbakiren arrayak, indizeak 0-tik 19-ra
void ArrayaBete(tafZerrenda afNotak, int *iLuzera);
void ArrayaIkusi(const tafZerrenda afNotak, int iLuzera);
void HainbatTartekaketa(tafZerrenda afNotak,
int *iLuzera,
int iNondik,
int iZenbat);
int main()
{
tafZerrenda afNotak;
int iLuzera, iZenbat, iNondik;
srand(time(NULL));
ArrayaBete(afNotak, &iLuzera);
ArrayaIkusi(afNotak, iLuzera);
if (iLuzera < GOIMUGA)
{
// Txertatzeko zenbat elementu eskatzen du
do
{
printf("Eman zenbat nota berri txertatuko diren (gehienez %d nota): ", GOIMUGA - iLuzera);
scanf("%d", &iZenbat);
if (iZenbat > GOIMUGA - iLuzera)
printf("Arrayan gehienez %d elementu berri txerta daitezke.\n", GOIMUGA - iLuzera);
} while (iZenbat < 1 || iZenbat > GOIMUGA - iLuzera);
// Txertatzeko posizioa eskatzen du
do
{
printf("Zenbaki berrien sortaren hasierako posizioa arrayan: ");
scanf("%d", &iNondik);
if (iNondik < BEHEMUGA || iNondik > iLuzera + 1)
printf("Hasierako posizioa %d eta %d artekoa izan dadila.\n", BEHEMUGA, iLuzera + 1);
} while (iNondik < BEHEMUGA || iNondik > iLuzera + 1);
HainbatTartekaketa(afNotak, &iLuzera, iNondik, iZenbat);
ArrayaIkusi(afNotak, iLuzera);
}
else
printf("Arraya beterik dago, ezin da elementu berririk txertatu.\n");
return 0;
}
// ArrayaBete() funtzioa
void ArrayaBete(tafZerrenda afNotak, int *iLuzera)
{
*iLuzera = rand() % GOIMUGA + 1; // 0 eta 19 arteko balioak
printf("Arrayan %d datu gordetzen...\n", *iLuzera + 1);
for (int iIndizea = BEHEMUGA; iIndizea <= *iLuzera; iIndizea++)
{
afNotak[iIndizea] = 10.0 * rand() / RAND_MAX; // 0.00 eta 9.99 arteko balioak
}
}
// ArrayaIkusi() funtzioa
void ArrayaIkusi(const tafZerrenda afNotak, int iLuzera)
{
printf("Arrayaren edukia:\n");
for (int iIndizea = BEHEMUGA; iIndizea <= iLuzera; iIndizea++)
{
printf("%9d. nota = %.3f\n", iIndizea, afNotak[iIndizea]);
}
printf("\n");
}
// HainbatTartekaketa funtzioa
void HainbatTartekaketa(tafZerrenda afNotak,
int *iLuzera,
int iNondik,
int iZenbat)
{
tafZerrenda afBerriak, afLaguntzailea;
int iLuzeraLagun = -1;
// Berria den balioak hartzea
for (int iIndizea = 0; iIndizea < iZenbat; iIndizea++)
{
printf("Eman sortaren %d. zenbaki berriaren balioa: ", iIndizea);
scanf("%f", &afBerriak[iIndizea]);
}
// Hasierako array kopiatzea laguntzailean iNondik posizioraino
for (int iIndizea = BEHEMUGA; iIndizea < iNondik; iIndizea++)
{
iLuzeraLagun++;
afLaguntzailea[iLuzeraLagun] = afNotak[iIndizea];
}
// Berria den balioak laguntzailean kopiatzea
for (int iIndizea = 0; iIndizea < iZenbat; iIndizea++)
{
iLuzeraLagun++;
afLaguntzailea[iLuzeraLagun] = afBerriak[iIndizea];
}
// Arrayko geratzen diren elementuak kopiatu laguntzailean
for (int iIndizea = iNondik; iIndizea <= *iLuzera; iIndizea++)
{
iLuzeraLagun++;
afLaguntzailea[iLuzeraLagun] = afNotak[iIndizea];
}
// Laguntzaileko edukia hasierako arrayra kopiatzea
for (int i = BEHEMUGA; i <= iLuzeraLagun; i++)
afNotak[i] = afLaguntzailea[i];
*iLuzera = iLuzeraLagun;
}
|

iruzkinik ez:
Argitaratu iruzkina