Dinamik massivlarni yaratish asoslari
![Dinamik massivlarni yaratish asoslari
MUNDARIJA
KIRISH .......................................................................................................................................................... 2
1.Dinamik massiv ......................................................................................................................................... 3
Dinamik massiv, shuningdek, o'lchamlarini o'zgartiradigan massiv sifatida ham tanilgan, bu ish vaqtida
uning imkoniyatlarini moslashuvchan o'lchamlarini o'zgartirishga imkon beradigan ma'lumotlar tuzilishi.
O'zgartirib bo'lmaydigan sobit o'lchamga ega bo'lgan statik massivlardan farqli o'laroq, dinamik
massivlar kerak bo'lganda o'sishi yoki kichrayishi mumkin. ......................................................................... 3
Dasturlashda dinamik massivlar odatda saqlanadigan ma'lumotlarning aniq hajmi noma'lum bo'lganda
yoki vaqt o'tishi bilan o'zgarishi mumkin bo'lganda ishlatiladi. Ushbu massivlar xotirani dinamik ravishda
ajratadi va ko'proq elementlarni qo'shish yoki mavjud elementlarni olib tashlash kerak bo'lganda
o'lchamlarini o'zgartirish mumkin. .............................................................................................................. 3
O'lchamini o'zgartirish jarayoni odatda yangi, kattaroq xotira blokini ajratishni, unga mavjud
elementlarni nusxalashni va eski xotira blokini taqsimlashni o'z ichiga oladi. Bu dinamik massivga xotirani
isrof qilmasdan ko'proq elementlarni joylashtirishga imkon beradi. Aksincha, agar elementlar olib
tashlansa, xotirani tejash uchun massiv qisqarishi mumkin. ....................................................................... 3
Dinamik massivlar statik massivlarga o'xshash samarali tasodifiy kirishning afzalliklarini taklif qiladi, shu
bilan birga dinamik o'lchamlarning moslashuvchanligini ta'minlaydi. Biroq, o'lchamlarni o'zgartirish
operatsiyalari vaqt jihatidan nisbatan qimmatga tushishi mumkin, chunki xotirani qayta taqsimlash va
nusxalash ishtirok etadi. .............................................................................................................................. 3
1.1. Dinamik massivlarni yaratish. ............................................................................................................... 5
1.2. Ko'p o'lchovli massivlar. ........................................................................................................................ 8
2. Ob'ektni dinamik massivga qo'shish va o’chirish ................................................................................... 15
2.1. Dinamik massivdan olib tashlash. ....................................................................................................... 16
2.2. Dinamik massiv uchun oddiy kod. ....................................................................................................... 18
3. Ma'lumotlar tuzilmalari ......................................................................................................................... 26
4. Dinamik massivlarning ishlashiga ta'sir qiluvchi omillar ......................................................................... 33
XULOSA ..................................................................................................................................................... 37
FOYDALANILGAN ADABIYOTLAR ................................................................................................................ 38
1](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_1.png)
![KIRISH
Dinamik massivlar birinchi marta kompyuter dasturlashda ma'lumotlar
tuzilishi tushunchasi sifatida kiritilgan. Ularning yaratilishining aniq tarixi har xil
bo'lishi mumkin, ammo ularning rivojlanishini dasturlash tillari va xotirani
boshqarish texnikasidagi yutuqlar bilan bog'lash mumkin. Dasturlashning dastlabki
kunlarida odatda ma'lumotlarni saqlash va boshqarish uchun sobit o'lchamdagi
massivlar ishlatilgan. Biroq, sobit o'lchamdagi massivlarning cheklanishi ishlab
chiquvchilar turli xil ma'lumotlarni joylashtirish uchun zarur bo'lganda yoki
dasturni bajarish paytida massivning hajmi dinamik ravishda o'zgarishi uchun
zarur bo'lganda aniq bo'ldi. Ushbu muammoning echimi sifatida dinamik massivlar
tushunchasi paydo bo'ldi. Belgilangan hajmdagi xotirani ajratish o'rniga, dinamik
massivlar haqiqiy hajm talablari asosida ish vaqtida xotirani ajratish va qayta
taqsimlashga imkon beradi. Massiv hajmini oshirish kerak bo'lganda, dinamik
massiv kattaroq xotira blokini ajratadi va mavjud ma'lumotlarni yangi xotira
maydoniga ko'chiradi. Xuddi shunday, massiv hajmini kamaytirish kerak
bo'lganda, massiv kichikroq xotira blokini qayta taqsimlashi va shunga mos
ravishda sozlashi mumkin. Dinamik massivlarni amalga oshirish va qo'llab-
quvvatlash yillar davomida turli dasturlash tillariga birlashtirilgan. Masalan, C++
da dinamik massivlar odatda "yangi" kalit so'z yordamida yaratiladi va
ko'rsatkichlar bilan boshqariladi. Python kabi boshqa tillar avtomatik ravishda
xotirani ajratish va dinamik massivlar uchun qayta taqsimlashni ro'yxatlar kabi
2](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_2.png)
![o'zlarining mahalliy ma'lumotlar tuzilmalari orqali boshqaradi. Umuman olganda,
dinamik massivlarning yaratilishi va evolyutsiyasi dasturlash tillarida
moslashuvchan ma'lumotlar tuzilmalariga bo'lgan ehtiyoj bilan bog'liq bo'lib,
ishlab chiquvchilarga dasturni bajarish paytida turli xil ma'lumotlarni samarali
boshqarish va boshqarish imkoniyatini beradi.
1.Dinamik massiv
Dinamik massiv, shuningdek, o'lchamlarini o'zgartiradigan massiv sifatida
ham tanilgan, bu ish vaqtida uning imkoniyatlarini moslashuvchan o'lchamlarini
o'zgartirishga imkon beradigan ma'lumotlar tuzilishi. O'zgartirib bo'lmaydigan
sobit o'lchamga ega bo'lgan statik massivlardan farqli o'laroq, dinamik massivlar
kerak bo'lganda o'sishi yoki kichrayishi mumkin.
Dasturlashda dinamik massivlar odatda saqlanadigan ma'lumotlarning aniq
hajmi noma'lum bo'lganda yoki vaqt o'tishi bilan o'zgarishi mumkin bo'lganda
ishlatiladi. Ushbu massivlar xotirani dinamik ravishda ajratadi va ko'proq
elementlarni qo'shish yoki mavjud elementlarni olib tashlash kerak bo'lganda
o'lchamlarini o'zgartirish mumkin.
O'lchamini o'zgartirish jarayoni odatda yangi, kattaroq xotira blokini
ajratishni, unga mavjud elementlarni nusxalashni va eski xotira blokini
taqsimlashni o'z ichiga oladi. Bu dinamik massivga xotirani isrof qilmasdan
ko'proq elementlarni joylashtirishga imkon beradi. Aksincha, agar elementlar olib
tashlansa, xotirani tejash uchun massiv qisqarishi mumkin.
Dinamik massivlar statik massivlarga o'xshash samarali tasodifiy kirishning
afzalliklarini taklif qiladi, shu bilan birga dinamik o'lchamlarning
moslashuvchanligini ta'minlaydi. Biroq, o'lchamlarni o'zgartirish operatsiyalari
vaqt jihatidan nisbatan qimmatga tushishi mumkin, chunki xotirani qayta
taqsimlash va nusxalash ishtirok etadi.
3](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_3.png)
![Dinamik massivlar dasturlash tillarida massiv hajmini kompilyatsiya vaqtida
emas, balki ish vaqtida aniqlash kerak bo'lgan vaziyatlarni boshqarish uchun
ishlatiladi. Dinamik massivlar uchun bir nechta umumiy foydalanish holatlari:
1. Dinamik xotirani taqsimlash: dinamik massivlar ish vaqtida massiv uchun
xotirani ajratishga imkon beradi, bu massiv hajmi oldindan ma'lum bo'lmaganda
yoki dasturni bajarish paytida o'zgarishi mumkin bo'lganda foydali bo'lishi
mumkin. Bu odatda C/C++ da `malloc()` yoki C++ yoki Java kabi tillarda `new`
operatori kabi funktsiyalar yordamida amalga oshiriladi.
2. Moslashuvchan ma'lumotlar tuzilmalari: dinamik massivlar ko'pincha
ro'yxatlar, stacklar, navbatlar va vektorlar kabi dinamik ma'lumotlar tuzilmalarini
amalga oshirish uchun ishlatiladi. Dinamik massivlar yordamida siz kerak
bo'lganda elementlarni osongina qo'shishingiz yoki olib tashlashingiz mumkin, bu
esa ma'lumotlarni samarali o'lchamlarini va manipulyatsiyasini ta'minlaydi.
3. Katta ma'lumotlar bilan ishlash: agar sizda dastlab xotiraga sig'maydigan
juda katta ma'lumotlar to'plamlari bo'lsa, dinamik massivlar ma'lumotlarning bir
qismini dinamik ravishda yuklash va boshqarish uchun ishlatilishi mumkin. Bu
katta ma'lumotlar to'plamlarini samarali qayta ishlash va manipulyatsiya qilish
imkonini beradi, chunki siz bir vaqtning o'zida ma'lumotlarning qismlarini
yuklashingiz va qayta ishlashingiz mumkin.
4. Resizable konteynerlarini amalga oshirish: dinamik massivlar odatda
Java-dagi ArrayList yoki C++ - dagi vektor kabi o'lchamli konteynerlar uchun
asosiy ma'lumotlar tuzilishi sifatida ishlatiladi. Ushbu konteynerlar elementlar
qo'shilishi yoki olib tashlanishi bilan massivning hajmini dinamik ravishda
o'zgartirish imkoniyatini beradi, bu ularni ma'lumotlar to'plamlarini boshqarish
uchun foydali qiladi.
Umuman olganda, dinamik massivlar dasturni bajarish paytida massiv hajmi
dinamik ravishda o'zgarishi kerak bo'lgan stsenariylarda moslashuvchanlikni
ta'minlaydi.
4](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_4.png)
![1.1. Dinamik massivlarni yaratish.
C++ tilidagi individual dinamik ob'ektlardan tashqari biz dinamik
massivlardan ham foydalanishimiz mumkin. Dinamik massivda xotirani ajratish
uchun new operatori ham ishlatiladi , shundan so'ng kvadrat qavs ichida massivda
nechta ob'ekt bo'lishi ko'rsatiladi:
int *numbers {new int[4]}; // 4 ta elementdan iborat massiv
// yoki
// int *numbers = new int[4];
Bundan tashqari, bu holda, yangi operator int tipidagi ob'ektga ko'rsatgichni
qaytaradi - yaratilgan massivning birinchi elementi.
Bunday holda, to'rtta int elementli massiv aniqlanadi, lekin ularning har biri
aniqlanmagan qiymatga ega. Biroq, biz qiymatlar bilan massivni ishga
tushirishimiz ham mumkin:
int *numbers1 {new int[4]{}}; // massiv elementlari 0, 0, 0, 0
int *numbers2 {new int[4]{ 1, 2, 3, 4 }}; // massiv elementlari 1, 2, 3, 4
int *numbers3 {new int[4]{ 1, 2 }}; // massiv elementlari 1, 2, 0, 0
// o'xshash massiv ta'riflari
// int *numbers1 = new int[4]{}; // massiv elementlari 0, 0, 0, 0
// int *numbers1 = new int[4](); // massiv elementlari 0, 0, 0, 0
// int *numbers2 = new int[4]{ 1, 2, 3, 4 }; // massiv elementlari 1, 2, 3, 4
// int *numbers3 = new int[4]{ 1, 2 }; // massiv elementlari 1, 2, 0, 0
Muayyan qiymatlar bilan massivni ishga tushirishda shuni yodda tutingki,
agar figurali qavslarda massiv uzunligidan ko'proq qiymatlar bo'lsa, yangi operator
ishlamay qoladi va massivni yarata olmaydi. Agar aksincha, kamroq qiymatlar
5](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_5.png)
![o'tgan bo'lsa, unda hech qanday qiymat ko'rsatilmagan elementlar standart qiymat
bilan ishga tushiriladi.
Shuni ta'kidlash kerakki, C++20 standarti massiv hajmini ko'rsatish
imkoniyatini qo'shdi, shuning uchun agar C++20 standarti ishlatilsa, unda siz
massiv uzunligini ko'rsata olmaysiz:
int *numbers {new int[]{ 1, 2, 3, 4 }}; // massiv elementlari 1, 2, 3, 4
Dinamik massivni yaratgandan so'ng, biz qabul qilingan ko'rsatgich
yordamida u bilan ishlashimiz, uning elementlarini olishimiz va o'zgartirishimiz
mumkin:
int *numbers {new int[4]{ 1, 2, 3, 4 }};
// massiv sintaksisi orqali elementlarni olish
std::cout << numbers[0] << std::endl; // 1
std::cout << numbers[1] << std::endl; // 2
// dereferent operatsiyasi orqali elementlarni olish
std::cout << *numbers << std::endl; // 1
std::cout << *(numbers+1) << std::endl; // 2
Bundan tashqari, dinamik massivning elementlariga kirish uchun siz massiv
sintaksisidan ( numbers[0]) va yo'qotish operatsiyasidan ( *numbers)
foydalanishingiz mumkin.
Shunga ko'ra, bunday massivni takrorlash uchun siz turli usullardan
foydalanishingiz mumkin:
unsigned n{ 5 }; // massiv o’lchami
int* p{ new int[n] { 1, 2, 3, 4, 5 } };
for (unsigned i{}; i < n; i++)
{
6](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_6.png)
![std::cout << p[i] << "\t";
}
std::cout << std::endl;
for (unsigned i{}; i < n; i++)
{
std::cout << *(p+i)<< "\t";
}
std::cout << std::endl;
// yordamchi ko'rsatgich yordamida massiv bo'ylab takrorlash
for (int* q{ p }; q != p + n; q++)
{
std::cout << *q << "\t";
}
std::cout << std::endl;
E'tibor bering, biz standart massivlarda bo'lgani kabi, dinamik massiv
hajmini o'rnatish uchun doimiy emas, oddiy o'zgaruvchidan foydalanishimiz
mumkin.
Dinamik massivni o'chirish va uning xotirasini bo'shatish uchun o'chirish
operatorining maxsus shakli qo'llaniladi :
delete []
dinamik_massivga ko'rsatgich;
Masalan:
#include <iostream>
7](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_7.png)
![int main()
{
unsigned n{ 5 }; // massiv o’lchami
int* p{ new int[n] { 1, 2, 3, 4, 5 } };
// indekslardan foydalaning
for (unsigned i{}; i < n; i++)
{
std::cout << p[i] << "\t";
}
std::cout << std::endl;
delete [] p;
}
Xotira bo'shatilgandan so'ng, ko'rsatgich eski manzilni saqlamasligi uchun
uni nolga qaytarish tavsiya etiladi:
delete [] p;
p = nullptr; // ko'rsatkichni nolga aylantiring
1.2. Ko'p o'lchovli massivlar.
Biz ko'p o'lchovli dinamik massivlarni ham yaratishimiz mumkin. Ikki
o'lchovli massivlar misolini ko'rib chiqaylik. Ikki o'lchovli massiv aslida nima? Bu
massivlar to'plamidir. Shunga ko'ra, dinamik ikki o'lchovli massivni yaratish uchun
biz ko'rsatkichlarning umumiy dinamik massivini, keyin esa uning elementlarini -
ichki o'rnatilgan dinamik massivlarni yaratishimiz kerak. Umuman olganda, u
quyidagicha ko'rinadi:
#include <iostream>
8](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_8.png)
![int main()
{
unsigned rows = 3; // qatorlar soni
unsigned columns = 2; // ustunlar soni
int** numbers{new int*[rows]{}}; // ikki o'lchovli massiv uchun xotira
ajratish
// ichki joylashtirilgan massivlar uchun xotira ajratish
for (unsigned i{}; i < rows; i++)
{
numbers[i] = new int[columns]{};
}
// massivlarni o'chirish
for (unsigned i{}; i < rows; i++)
{
delete[] numbers[i];
}
delete[] numbers;
}
Birinchidan, biz ko'rsatkichlar majmuasi uchun xotira ajratamiz (shartli
jadvallar):
int** numbers{new int*[rows]{}};
Keyin, tsiklda biz har bir alohida massiv uchun xotira ajratamiz (shartli
jadval qatorlari):
numbers[i] = new int[columns]{};
9](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_9.png)
![Xotirani chiqarish teskari tartibda amalga oshiriladi - avval biz xotirani har
bir ichki o'rnatilgan massiv uchun, keyin esa butun ko'rsatkichlar massivi uchun
bo'shatamiz.
Ikki o'lchovli dinamik massivning ma'lumotlarini kiritish va chiqarishga
misol:
#include <iostream>
int main()
{
unsigned rows = 3;
unsigned columns = 2;
int** numbers{new int*[rows]{}};
// ikki o'lchovli massiv uchun xotira ajratish
for (unsigned i{}; i < rows; i++)
{
numbers[i] = new int[columns]{};
}
// jadval satrlari x ustunlari uchun ma'lumotlarni kiriting
for (unsigned i{}; i < rows; i++)
{
std::cout << "Enter data for " << (i + 1) << " row" << std::endl;
// i-qator ustunlari uchun ma'lumotlarni kiriting
for (unsigned j{}; j < columns; j++)
{
10](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_10.png)
![std::cout << (j + 1) << " column: ";
std::cin >> numbers[i][j];
}
}
// ma'lumotlar chiqishi
for (unsigned i{}; i < rows; i++)
{
// i-qator ustunlari ma'lumotlarini ko'rsatish
for (unsigned j{}; j < columns; j++)
{
std::cout << numbers[i][j] << "\t";
}
std::cout << std::endl;
}
for (unsigned i{}; i < rows; i++)
{
delete[] numbers[i];
}
delete[] numbers;
}
Dasturning ishlashiga misol:
1 qator uchun ma'lumotlarni kiriting
11](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_11.png)
![1 ustun: 2
2 ustun: 3
2 qator uchun ma'lumotlarni kiriting
1 ustun: 4
2 ustun: 5
3 qator uchun ma'lumotlarni kiriting
1 ustun: 6
2 ustun: 7
2 3
4 5
6 7
1.3. Massivga ko'rsatgich .
Int ** massivga ko'rsatgich e’lon qilish. Masalan:
#include <iostream>
int main()
{
unsigned n{3}; // qatorlar soni
int (*a)[2] = new int[n][2];
int k{};
// qiymatlarni o'rnatish
for (unsigned i{}; i < n; i++)
{
// i-qator ustunlari uchun ma'lumotlarni o'rnating
12](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_12.png)
![for (unsigned j{}; j < 2; j++)
{
a[i][j] = ++k;
}
}
// ma'lumotlar chiqishi
for (unsigned i{}; i < n; i++)
{
// i-qator ustunlari ma'lumotlarini ko'rsatish
for (unsigned j{}; j < 2; j++)
{
std::cout << a[i][j] << "\t";
}
std::cout << std::endl;
}
// ma'lumotlarni o'chirish
delete[] a;
a = nullptr;
}
Bu erda yozuv int (*a)[2]ikkita int elementli massivga ko'rsatgichni
ifodalaydi. Aslida, biz ushbu ob'ekt bilan ikki o'lchovli massiv (jadval) bilan
ishlashimiz mumkin, bu holda faqat ustunlar soni aniqlangan - 2. Va bunday
massiv uchun xotira bir marta ajratiladi:
13](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_13.png)
![int (*a)[2] = new int[n][2];
Ya'ni, bu holda biz n satr va 2 ustundan iborat jadval bilan ishlaymiz. Ikkita
indeksdan (biri satr uchun, biri ustun uchun) foydalanib, ma'lum bir elementga
kirish, uning qiymatini belgilash yoki olish mumkin.
Dinamik massivlarning kamchiliklari. Aytaylik, biz massivga juda katta
ob’ektlarni tez-tez qo'shishimiz va olib tashlashimiz kerak. Bunday holda, ob'ektlar
ko'pincha boshqa joylarga ko'chirilishi mumkin va ko'plab ko'rsatkichlar bekor
bo'ladi. Agar siz dinamik massivning o'rtasida tez-tez o'zgartirishlar kiritishingiz
kerak bo'lsa, unda buning uchun chiziqli ma'lumotlar strukturasining yanada mos
turi mavjud.
14](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_14.png)
![2. Ob'ektni dinamik massivga qo'shish va o’chirish
Ob'ekt dinamik massivga qo'shilsa, bir nechta narsa sodir bo'ladi. Massiv
klassi unda yetarli joy mavjudligini tekshiradi. Agar currentLength <
maxCapacity bo'lsa, massivda qo'shish uchun joy mavjud. Agar etarli joy bo'lmasa,
u holda kattaroq ichki massiv joylashtiriladi va hamma narsa yangi ichki massivga
ko'chiriladi. MaxCapacity qiymati yangi kengaytirilgan qiymatga oshiriladi. Agar
etarli joy bo'lsa, yangi element qo'shiladi. Qo'shish nuqtasidan keyingi har bir
element ichki massivdagi qo'shni joyga ko'chirilishi kerak va nusxa ko'chirish
tugagach, bo'sh joy yangi ob'ekt bilan to'ldiriladi va currentLength qiymati bittaga
oshiriladi .
1- Rasm : Dinamik massivga element qo ’ shish
Qo ' shish nuqtasidan keyin har bir ob ' ektni ko ' chirish zarur bo ' lganligi
sababli , eng yaxshi holat elementni oxiriga qo ' shishdir . Bunday holda, nol
elementlarni ko'chirish kerak (ammo, ichki massiv hali ham kengaytirilishi
kerak). Dinamik massiv elementni o'rtada emas, balki oxiriga qo'shganda yaxshi
ishlaydi.
Element qo'shish: Agar massiv o'lchami etarli bo'lmasa, oxiriga element
qo'shing, keyin massiv hajmini kengaytiring va asl massivning oxiriga elementni,
15](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_15.png)
![shuningdek berilgan indeksni qo'shing. Barcha nusxa ko'chirish O(n) vaqtini oladi,
bu erda n - massivimizdagi elementlar soni. Bu qo'shimcha uchun qimmat
turadi. Ruxsat etilgan uzunlikdagi massivda qo'shimchalar faqat O (1) vaqtni
oladi. Ammo qo'shimchalar faqat to'liq massivga kiritganimizda O(n) vaqtini oladi
va bu juda kam uchraydi, ayniqsa har safar bo'sh joy tugashi bilan massiv hajmini
ikki baravar oshirsak. Shunday qilib, ko'p hollarda qo'shish hali ham O (1) vaqt,
ba'zan esa O (n) vaqti. Dinamik massivda siz qat'iy o'lchamli massiv yaratishingiz
mumkin, agar kerak bo'lsa, massivga yana bir nechta element qo'shiladi va keyin
ushbu yondashuvdan foydalaniladi:
2-Rasm: Dinamik massivga element qo’shish
Ob'ektni dinamik massivga qo'shganda, har bir ob'ekt xotirada harakatlanishi
mumkin. C va C++ kabi tillarda dinamik massivga qo‘shish massiv obyektlariga
barcha ko‘rsatgichlar yaroqsiz bo‘lishini anglatadi.
2.1. Dinamik massivdan olib tashlash.
Ob'ektlarni olib tashlash ularni qo'shishdan ko'ra kamroq ish talab
qiladi. Birinchidan, ob'ektning o'zi yo'q qilinadi. Ikkinchidan, bu nuqtadan keyin
har bir ob'ekt bitta element bilan siljiydi. Nihoyat, joriy uzunlik bittaga kamayadi.
16](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_16.png)
![3-Rasm: Dinamik massivdan elementni olib tashlash
Massiv oxiriga qo'shishda bo'lgani kabi, massiv oxiridan olib tashlash ham
eng yaxshisidir, chunki ko'chirish uchun nol ob'ekt mavjud. Shuni ham ta'kidlash
kerakki, biz ichki massivni kichikroq qilish uchun o'lchamini o'zgartirishimiz shart
emas. Agar ob'ektlarni keyinroq qo'shsak, ajratilgan joy bir xil bo'lishi mumkin.
Elementni o'chirish: elementni massivdan o'chirish, standart remove() usuli
elementni oxiridan o'chirish, shunchaki oxirgi indeksda nolni saqlash va i indeks
bo'lgan removeAt(i) usulini chaqirish orqali ma'lum bir indeksdagi elementni
o'chiring, removeAt(i) usuli chap tomondagi barcha o'ng elementni berilgan
indeksdan siljitadi.
4-Rasm: Dinamik massivdan elementni remove() orqali olib tashlash
17](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_17.png)
![Ob'ektni dinamik massivdan olib tashlash, olib tashlangan elementdan keyin
hamma narsaning xotirasida siljishga olib keladi. C va C++ kabi tillarda dinamik
massivdan o chirish o chirilgan massivdan keyin hamma narsaga ko rsatgichlar ʻ ʻ ʻ
yaroqsiz bo lishini anglatadi
ʻ
Massiv hajmining o‘lchamini o‘zgartirish: Agar massivning o‘ng tomonida
nol/nol ma’lumotlar (siz qo‘shgan elementdan tashqari) bo‘lsa, ya’ni u
foydalanilmagan xotiraga ega bo‘lsa, shrinkSize() usuli qo‘shimcha xotirani
bo‘shatishi mumkin. Qachonki, barcha bo'sh joy iste'mol qilinsa va qo'shimcha
element qo'shilishi kerak bo'lsa, asosiy o'lchamli massiv hajmini oshirishi
kerak. Odatda o‘lchamini o‘zgartirish qimmatga tushadi, chunki biz elementimizni
qo‘shishimizdan oldin kattaroq massivni ajratib, o‘zidan oshib ketgan massivning
barcha elementlarini nusxalashimiz kerak.
5-Rasm: Dinamik massivdan growSize() va shrinkSize() funksiyalari
2.2. Dinamik massiv uchun oddiy kod.
18](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_18.png)
![Quyidagi kodda massiv o'lcham bilan to'la bo'ladi, biz barcha elementni
yangi ikki o'lchamli massivga (o'zgaruvchan o'lchamli massiv) ko'chiramiz. Kod
namunasi quyida keltirilgan:
#include <iostream>
using namespace std;
class DynamicArray {
private:
// Pointer to store array created
// using new keyword
int* array = NULL;
// Size of array
int size;
// Container size
int capacity;
public:
// Default constructor with size 1
DynamicArray()
{
capacity = 1;
size = 0;
array = new int[capacity];
}
// Taking size from the user
DynamicArray(int capacity)
{
this->capacity = capacity;
array = new int[capacity];
size = 0;
}
19](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_19.png)
![// Returns the size of Array
// i.e Total elements stored currently
int getSize() { return size; }
// Returns the size of container
int getCapacity() { return capacity; }
// Inserting element after last stored index
void push_back(int value)
{
// check is array having size to store element or
// not
if (size == capacity) {
// if not then grow the array by double
growArray();
}
// insert element
array[size] = value;
// increment the size or last_index+1
size++;
}
// Deleting element at last stored index
void pop_back()
{
// Replace the last index by 0
array[size - 1] = 0;
// Decrement the array size
size--;
// Reduce if the container half element of its
// capacity
if (size == (capacity / 2)) {
20](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_20.png)
![shrinkArray();
}
}
// Increase the array size by double of current capacity
void growArray()
{
// Creating new array of double size
int* temp = new int[capacity * 2];
capacity = capacity * 2;
// copy element of old array in newly created array
for (int i = 0; i < size; i++) {
temp[i] = array[i];
}
// Delete old array
delete[] array;
// Assign newly created temp array to original array
array = temp;
}
// Reduce the size of array by half
void shrinkArray()
{
// Creating new array of half size
capacity = size;
int* temp = new int[capacity];
// copy element of old array in newly created array
for (int i = 0; i < size; i++) {
temp[i] = array[i];
}
21](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_21.png)
![// Delete old array
delete[] array;
// Assign newly created temp array to original array
array = temp;
}
// Searching element in the given array
int search(int key)
{
for (int i = 0; i < size; i++) {
if (array[i] == key) {
// If element found return its index
return i;
}
}
// Return -1 if element not found;
return -1;
}
// Insert element at given index
void insertAt(int index, int value)
{
// check is array having size to store element or
// not
if (size == capacity) {
// if not then grow the array by double
growArray();
}
for (int i = size - 1; i >= index; i--) {
array[i + 1] = array[i];
}
22](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_22.png)
![array[index] = value;
size++;
}
// Delete element at given index
void deleteAt(int index)
{
for (int i = index; i < size; i++) {
array[i] = array[i + 1];
}
// Replace the last index by 0
array[size - 1] = 0;
// Decrement the array size
size--;
// Reduce if the container half element of its
// capacity
if (size == (capacity / 2)) {
shrinkArray();
}
}
// To Print Array
void printArrayDetails()
{
cout << "Elements of array : ";
for (int i = 0; i < size; i++) {
cout << array[i] << " ";
}
cout << endl;
cout << "No of elements in array : " << size
<< ", Capacity of array :" << capacity << endl;
23](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_23.png)
![}
bool isEmpty()
{
if (size == 0) {
return true;
}
else {
return false;
}
}
};
int main()
{
DynamicArray da;
da.push_back(1);
da.push_back(2);
da.push_back(3);
da.push_back(4);
da.push_back(5);
da.push_back(6);
da.push_back(7);
da.push_back(8);
da.push_back(9);
da.push_back(10);
da.push_back(11);
da.printArrayDetails();
da.shrinkArray();
cout << "\nCapacity of array after shrinking : "
<< da.getCapacity() << endl;
24](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_24.png)
![cout << "\nAfter inserting at index 3 " << endl;
da.insertAt(3, 50);
da.printArrayDetails();
cout << "\nAfter delete last element ";
da.pop_back();
da.printArrayDetails();
cout << "\nAfter deleting at index 3 ";
da.deleteAt(3);
da.printArrayDetails();
cout << "\nSearching 5 in array ";
int index = da.search(5);
if (index != -1) {
cout << "Element found at index : " << index << endl;
}
else {
cout << "Element not found " << endl;
}
return 0;
}
Chiqish
Massiv elementlari: 1 2 3 4 5 6 7 8 9 10 11
Massivdagi elementlar soni: 11, massiv sig‘imi: 16
Qisqartirilgandan keyin massivning sig'imi: 11
Indeks 3 ga kiritilgandan so'ng
Massiv elementlari: 1 2 3 50 4 5 6 7 8 9 10 11
Massivdagi elementlar soni: 12, massiv sig‘imi:22
25](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_25.png)
![Oxirgi element o'chirilgandan so'ng Massiv elementlari: 1 2 3 50 4 5 6 7 8 9 10
Massivdagi elementlar soni: 11, massiv sig‘imi:11
Indeks 3 da o'chirilgandan so'ng Massiv elementlari: 1 2 3 4 5 6 7 8 9 10
Massivdagi elementlar soni: 10, massiv sig‘imi:11
Massivda 5 izlanmoqda Indeksda topilgan element: 4
3. Ma'lumotlar tuzilmalari
Bog'langan ro'yxatlar. Massiv xotiraning ulashgan blokidir va har bir
element ikkinchisidan keyin joylashgan. Bog'langan ro'yxat ob'ektlar
zanjiridir. Bog'langan ro'yxatlar asosiy dasturlash tillarining standart
kutubxonalarida ham mavjud. C++ da ular list deb ataladi . Java va C# da
bu LinkedList . Bog'langan ro'yxat bir qator tugunlardan iborat. Har bir tugun
quyidagicha ko'rinadi:
// Bog'langan ro'yxat tugun
sometype data;
Node* next;
U shunday strukturani yaratadi:
6-Rasm: Dinamik massivda tugunlarning o’zaro ulanishi
Har bir tugun keyingisiga ulanadi.
Ob'ektni bog'langan ro'yxatga qo'shish yangi tugunni yaratish bilan
boshlanadi. Ma'lumotlar tugun ichida ko'chiriladi. Keyin kiritish nuqtasi
mavjud. Yangi tugunning keyingi ob'ektga ko'rsatgichi keyingi tugunga ishora
26](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_26.png)
![qilish uchun o'zgartiriladi. Nihoyat, yangi tugun oldidagi tugun o'z ko'rsatkichini
yangi tugunga ishora qilish uchun o'zgartiradi.
7-Rasm: Ob'ektni bog'langan ro'yxatga qo'shish.
Bog'langan ro'yxatdan o'chirish. Ob'ekt bog'langan ro'yxatdan o'chirilganda,
tugunni olib tashlashdan oldin tugun mavjud. U o'chirilgan ob'ektdan keyingi
tugunga ishora qilish uchun o'zgartiriladi. Shundan so'ng, o'chirilgan ob'ekt xavfsiz
tarzda o'chirilishi mumkin.
8-Rasm: Ob'ektni bog'langan ro'yxatdan o’chirish.
Bog'langan ro'yxatning afzalliklari. Bog'langan ro'yxatning eng katta foydasi
ro'yxatga ob'ektlarni qo'shish va olib tashlashdir. Ro'yxatning o'rtasiga
o'zgartirishlar kiritish juda tez. Dinamik massiv nazariy jihatdan har bir
elementning siljishiga olib kelishi mumkinligini unutmang, bog'langan ro'yxat esa
har bir boshqa ob'ektni joyida ushlab turadi.
Bog'langan ro'yxatning kamchiliklari. Eslatib o'tamiz, dinamik massiv
xotiraning qo'shni blokidir. Agar siz massivning 500-elementini olishingiz kerak
bo'lsa, oldiniga 500 ta joyni qarang. Bog'langan ro'yxatda xotira bir-biriga
bog'langan. Agar siz besh yuzinchi elementni topishingiz kerak bo'lsa, siz
zanjirning boshidan boshlashingiz va uning ko'rsatgichini keyingi elementga,
so'ngra keyingi elementga va shunga o'xshash besh yuz marta takrorlashingiz
kerak.
Bog'langan ro'yxatga tasodifiy kirish juda sekin. Har bir tugunga biroz
27](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_27.png)
![qo'shimcha joy kerak. Unga qancha joy kerak? Siz unga faqat ko'rsatgich hajmi
kerak deb o'ylashingiz mumkin, ammo bu mutlaqo to'g'ri emas. Ob'ektni dinamik
ravishda yaratishda har doim kichik chegara mavjud. Ba'zi dasturlash tillari,
masalan, C++ xotira sahifalari bilan ishlaydi. Odatda sahifa 4 kilobaytni tashkil
qiladi. Qo'shish va o'chirish operatorlaridan foydalanganda, faqat bitta baytdan
foydalanish kerak bo'lsa ham, xotiraning butun sahifasi ajratiladi.
Java va C# da jarayonlar biroz boshqacha, ular kichik ob'ektlar uchun
maxsus qoidalarga ega. Ushbu tillar xotiraning butun 4K sahifasini talab qilmaydi,
lekin ular hali ham kichik bo'shliqqa ega. Agar siz standart kutubxonalardan
foydalansangiz, ikkinchi kamchilik haqida tashvishlanishingiz shart emas. Ular
bo'sh joyni minimallashtiradigan tarzda yozilgan.
Ushbu uch tur (massiv, dinamik massiv va bog'langan ro'yxat) deyarli
barcha murakkabroq ma'lumotlar konteynerlari uchun asos bo'lib xizmat qiladi.
Ma'lumotlar tuzilmalarini o'rganishdagi birinchi vazifalardan biri o'zimizning
dinamik massiv va bog'langan ro'yxat sinflarimizni yaratishimizdir.
Stak . Tasavvur qilamiz, bizda bir varaq qog'oz bor. Biz bitta varaqni qoziqqa
solamiz. Endi biz faqat yuqori varaqqa kira olamiz. Biz qoziqqa yana bir varaq
qo'yamiz. Oldingi varaq endi yashirin va unga kirish imkonsiz, biz yuqori
varaqdan foydalanishimiz mumkin. Yuqori varaq bilan ishlaganimizdan so'ng, biz
uni taglikdan olib tashlashimiz mumkin va ostidagini ko'rsatamiz mumkin.
Bu stek ortidagi g'oya. Stack LIFO strukturasidir. Bu oxirgi kiruvchi birinchi
chiqadi degan ma'noni anglatadi. Stakka qo'shish va undan olib tashlashda oxirgi
qo'shilgan element olib tashlangan birinchi element bo'ladi.
Stack faqat uchta operatsiyani talab qiladi: Push, Pop va Top.
Push ob'ektni stekga qo'shadi. Pop ob'ektni stekdan olib tashlaydi. Top bu
yuqori stekdagi eng oxirgi ob'ektni beradi. Ushbu konteynerlar aksariyat tillardagi
standart kutubxonalarning bir qismidir. C++ da ular stack deb ataladi . Java va C#
da bu Stack . (Ha, yagona farq katta harflar bilan yozilgan nomdir.) Ichkarida stek
ko'pincha dinamik massiv sifatida amalga oshiriladi. Ushbu ma'lumotlar
28](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_28.png)
![strukturasidan eslaganingizdek, dinamik massivlardagi eng tezkor operatsiyalar
elementlarni oxiridan qo'shish va olib tashlashdir. Stack har doim oxirigacha
qo'shishi va olib tashlashi sababli, odatda stekdagi ob'ektlarni surish va ochish juda
tezdir.
Navbat . Tasavvur qilamiz, biz biror narsa uchun navbatda turibsiz.
Navbatdagi birinchi odamga xizmat qilinadi, keyin esa ketadi. Keyin unga xizmat
ko'rsatiladi va ikkinchi navbatdan ketadi. Boshqa odamlar navbatga kelishadi va
uning oxirida turishadi. Bu navbat ma'lumotlar strukturasi ortidagi g'oya.
Navbat FIFO (First In First Out) tuzilmasi hisoblanadi. Navbatni qo'shish va
o'chirishda birinchi qo'shilgan element olib tashlangan birinchi element
bo'ladi. Navbat faqat bir nechta operatsiyalarni talab qiladi: Push_Back elementni
navbat oxiriga qo'shadi. Pop_Front navbatning old qismidan elementni olib
tashlaydi. Back va Front navbatning ikki uchiga kirish imkonini beradi.
Dasturchilar ko'pincha navbatning ikkala uchidan elementlarni qo'shishlari
yoki olib tashlashlari kerak. Ushbu struktura ikki tomonlama navbat (deque) deb
ataladi. Bunday holda, yana bir nechta operatsiyalar qo'shiladi: Push_Front va
Push_Back. Ushbu konteynerlar ko'pgina asosiy tillarda ham mavjud. C++ da
bular navbat va deque. Java navbat va deque uchun interfeyslarni belgilaydi va
keyin ularni LinkedList orqali amalga oshiradi . C# da Queue klassi bor , lekin
Deque sinfi yo'q.
Navbat va deque juda murakkab bo'lishi mumkin. Ob'ektlar har ikki uchidan
ham kirishi va chiqishi mumkinligi sababli, ichki idish o'sishi va navbatni boshidan
va oxiridan qisqartirishi kerak. Ko'pgina ilovalar bir nechta xotira sahifalaridan
foydalanadi. Har ikki uchi joriy sahifadan oshib ketganda, qo'shimcha sahifa
qo'shiladi. Agar sahifa endi kerak bo'lmasa, u o'chiriladi. Java xotira sahifalari esa
bog'langan ro'yxat uchun biroz qo'shimcha xotiradan foydalanadi, ammo bu dastur
ushbu til uchun yaxshi ishlaydi.
29](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_29.png)
![U stuvor navbat . Bu navbatning juda keng tarqalgan turi. Ustuvor navbat
oddiy navbatga juda o'xshaydi.
Dastur elementlarni oxiridan qo'shadi va elementlarni boshidan olib
tashlaydi. Farqi shundaki, siz navbatning ayrim elementlari uchun ustuvorliklarni
belgilashingiz mumkin. Barcha eng muhim elementlar FIFO tartibida qayta
ishlanadi. Keyinchalik pastroq ustuvor elementlar FIFO tartibida qayta
ishlanadi. Shunday qilib, eng past ustuvorlikka ega bo'lgan elementlar FIFO
tartibida qayta ishlanmaguncha takrorlanadi.
Navbatning qolgan qismidan yuqoriroqga yangi element qo'shilsa, u darhol
navbatning old qismiga o'tkaziladi. C++ da bu tuzilma priority_queue deb ataladi.
Java-da bu PriorityQueue deb ataladi. C# standart kutubxonasida ustuvor navbat
yo'q. Ustuvor navbatlar tashkilot printeri uchun birinchi navbatda turishdan ko'ra
ko'proq foydalidir. Ulardan A* qidiruv protsedurasi kabi algoritmlarni qulay tarzda
amalga oshirish uchun foydalanish mumkin. Eng mumkin bo'lgan natijalarga
yuqoriroq ustuvorlik berilishi mumkin, natijalar kamroq bo'lishi mumkin. Siz A*
qidiruvlarini saralash va buyurtma qilish uchun o'z tizimingizni yaratishingiz
mumkin, ammo o'rnatilgan ustuvor navbatdan foydalanish ancha oson.
Staklar, navbatlar, dequelar va ustuvor navbatlar boshqa ma'lumotlar
tuzilmalari yordamida amalga oshirilishi mumkin. Bu asosiy ma'lumotlar
tuzilmalari emas, lekin ular tez-tez ishlatiladi. Ular faqat yakuniy ma'lumotlar
elementlari bilan ishlash kerak bo'lganda juda samarali bo'ladi va o'rta elementlar
muhim emas.
U yum . Yig'ma ma'lumotlar strukturasi asosan daraxt bilan bir xil. U ildiz
tuguniga ega, har bir tugunda bola tugunlari mavjud va hokazo. Uyum har doim
ma'lum bir tartibda saralanishi kerak bo'lgan cheklovni qo'shadi. Saralash
funktsiyasi talab qilinadi - odatda kamroq operator.
Ob'ektlar qo'shilishi yoki yig'ilishdan olib tashlanishi natijasida struktura
o'zini "to'liq" daraxtga aylantiradi, daraxtning har bir darajasi to'ldirilgan, ehtimol
faqat oxirgi qatordan tashqari, hamma narsani bir tomonga siljitish kerak. Bu
30](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_30.png)
![saqlash joyini va yig'ish qidirishni ta'minlashni juda samarali qiladi.
Uyumlar oddiy yoki dinamik massivda saqlanishi mumkin, ya'ni uni ajratish
uchun kam joy talab etiladi. C++ push_heap() va pop_heap() kabi funksiyalarni o'z
konteyneringizda to'plash imkonini beradi. Java va C# standart kutubxonalari
o'xshash funksiyalarga ega emas. Mana bir xil ma'lumotga ega bo'lgan daraxt va
uyum:
9-Rasm: Daraxt va uyum.
Biz odatda to'plamning tartibiga ahamiyat bermaymiz, biz faqat boshidan
boshlaymiz va har bir elementga tashrif buyuramiz. Ushbu juda keng tarqalgan
vaziyatda ma'lumotlar strukturasini tanlash juda muhim emas.
Shubha tug'ilganda, dinamik massiv odatda eng yaxshi tanlovdir. U har
qanday hajmgacha o'sishi mumkin va nisbatan neytral bo'lib, uni keyinchalik
boshqa ma'lumotlar tuzilmasi bilan almashtirish juda oson. Ammo ba'zida tuzilish
juda muhim.
O'yinlarda eng ko'p uchraydigan vazifalardan biri bu yo'lni aniqlash: A
nuqtadan B nuqtasiga marshrutni topishingiz kerak. Eng keng tarqalgan yo'lni
aniqlash algoritmlaridan biri A*. Algoritm A* qisman yo'llarni o'z ichiga olgan
ma'lumotlar strukturasiga ega. Struktura shunday saralanganki, qisman yo'l
idishning old tomonida bo'lishi mumkin. Bu yo'l baholanadi va agar u to'liq
bo'lmasa, algoritm bu qisman yo'lni bir nechta katta qisman yo'llarga aylantiradi va
31](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_31.png)
![keyin ularni konteynerga qo'shadi.
Ushbu konteyner sifatida dinamik massivdan foydalanish bir necha
sabablarga ko'ra yomon tanlov bo'ladi. Birinchidan, dinamik massivning boshidan
elementlarni olib tashlash biz bajarishimiz mumkin bo'lgan eng sekin
operatsiyalardan biridir. Ikkinchidan, har bir qo'shilgandan keyin dinamik massivni
qayta tartiblash ham sekin bo'lishi mumkin. Yuqoridagilardan eslaganingizdek,
ushbu turdagi kirish uchun optimallashtirilgan ma'lumotlar tuzilmasi mavjud. Biz
boshidan olib tashlaymiz va oxiridan qo'shamiz va avtomatik saralash qaysi yo'l
eng yaxshi ekanligiga qarab amalga oshiriladi. A* yo'l konteyneri uchun ideal
tanlov tilga kiritilgan va to'liq disk raskadrovkani ta'minlaydigan ustuvor
navbatdir.
Dinamik massiv - standart tanlovdir. Shubha tug'ilganda, dinamik massivdan
foydalaning. C++ da bu vektor . Java-da u ArrayList deb ataladi . C# da
bu ro'yxat . Umuman olganda, dinamik massiv bizga asqotadi.
32](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_32.png)
![4. Dinamik massivlarning ishlashiga ta'sir qiluvchi omillar
Massivning boshlang'ich hajmi va uning o'sish omili uning ishlashini
belgilaydi. Quyidagi fikrlarga e'tibor bering:
Agar massiv kichik o'lchamga va kichik o'sish omiliga ega bo'lsa, u xotirani
tez-tez qayta taqsimlashni davom ettiradi. Bu massivning ishlashini pasaytiradi.
Agar massiv katta hajmga va katta o'sish omiliga ega bo'lsa, unda
foydalanilmagan xotiraning katta qismi bo'ladi. Shu sababli, o'lchamini o'zgartirish
operatsiyalari ko'proq vaqt talab qilishi mumkin. Bu massivning ishlashini
pasaytiradi.
Yangi kalit so'z. C++ da biz new kalit so'zidan foydalanib dinamik massiv
yaratishimiz mumkin. Ajraladigan elementlar soni bir juft kvadrat qavs ichida
ko'rsatilgan. Tur nomi bundan oldin bo'lishi kerak. Elementlarning so'ralgan soni
ajratiladi.
Sintaksis: Yangi kalit so'z quyidagi sintaksisni oladi:
pointer_variable = new data_type;
Pointer_variable - bu ko'rsatkich o'zgaruvchisining nomi.
Data_type to'g'ri C++ ma'lumotlar turi bo'lishi kerak.
Keyin kalit so'z birinchi elementga ko'rsatgichni qaytaradi. Dinamik
massivni yaratgandan so'ng, biz uni delete kalit so'zi yordamida o'chirishimiz
mumkin.
33](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_33.png)
![Misol:
#include<iostream>
using namespace std;
int main() {
int x, n;
cout << "Enter the number of items:" << "\n";
cin >>n;
int *arr = new int(n);
cout << "Enter " << n << " items" << endl;
for (x = 0; x < n; x++) {
cin >> arr[x];
}
cout << "You entered: ";
for (x = 0; x < n; x++) {
cout << arr[x] << " ";
}
return 0;
}
Kod tushuntirilishi:
Funktsiyalardan foydalanish uchun iostream sarlavha faylini dasturimizga
qo'shamiz.
Std nom maydonini standart nomlar fazosidan foydalanish uchun
dasturimizga qo'shamiz.
34](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_34.png)
![Main() funktsiyasini chaqiramiz. Dastur mantig'i funktsiya tanasiga
qo'shilishi kerak.
X va n ikkita butun o'zgaruvchini e'lon qiling.
Konsolda foydalanuvchidan n o'zgaruvchisi qiymatini kiritishni taklif
qiluvchi matnni chop eting.
Klaviaturadan foydalanuvchi ma'lumotlarini o'qiymiz va uni n
o'zgaruvchisiga tayinlaymiz.
Jami n ta butun sonni ushlab turish uchun massivni e'lon qilamiz va uni *arr
ko'rsatkich o'zgaruvchisiga tayinlaymiz.
Foydalanuvchiga n ta elementni kiritishni taklif qiluvchi xabarni chop
etamiz.
Foydalanuvchi tomonidan kiritilgan elementlarni takrorlash uchun x tsikli
o'zgaruvchisini yaratish uchun for tsiklidan foydalanamiz.
Foydalanuvchi tomonidan kiritilgan elementlarni o'qiymiz va ularni
massivda saqlaymiz.
For tsikli tanasining oxiri.
Konsolda bir nechta matnni chop etamiz.
Massiv elementlarini takrorlash uchun x tsikli o'zgaruvchisini yaratish uchun
for tsiklidan foydalanamiz.
Konsolda arr nomli massivdagi qiymatlarni chop etamiz.
For tsikli tanasining oxiri.
Muvaffaqiyatli tugallangandan so'ng dastur qiymatni qaytarishi kerak.
Main() funktsiyasi tanasining oxiri.
Massivlarni dinamik ravishda yo'q qilish. Dinamik massiv maqsadi
bajarilgandan so'ng kompyuter xotirasidan o'chirilishi kerak. O'chirish bayonoti
35](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_35.png)
![buni amalga oshirishga yordam beradi. Keyin bo'shatilgan xotira maydoni boshqa
ma'lumotlar to'plamini saqlash uchun ishlatilishi mumkin. Biroq, dinamik massivni
kompyuter xotirasidan o'chirmasangiz ham, dastur tugagandan so'ng u avtomatik
ravishda o'chiriladi. Eslatma:
Dinamik massivni kompyuter xotirasidan o chirish uchun delete[] dan ʻ
foydalaning. [] protsessorga bitta o'zgaruvchini emas, balki bir nechta
o'zgaruvchilarni o'chirishni buyuradi. Dinamik massiv bilan ishlashda
delete[] o‘rniga o‘chirishdan foydalanish muammolarga olib kelishi
mumkin. Bunday muammolarga misollar xotiraning oqishi, ma'lumotlarning
buzilishi, buzilishlar va boshqalarni o'z ichiga oladi.
36](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_36.png)
![XULOSA
Xulosa qilib shuni aytish mumkinki , C++ dasturlash tilida ishlash boshqa
dasturlash tillariga nisbatan ancha qulay va imkonoyati ham kengroq. Men C+
+ dasturi strukturasi xaqida, belgilar bayoni , Algoritm va dastur tushunchasi, ma’lum
otlarni kiritish va chikarish operatorlari xamda dasturda massivlar va satrlar bilan ishl
ash xaqida o`zimga keraklicha bilim va ko`nikmaga ega bo`ldim.
C++dasturi Windows muhitida ishlaydigan dastur tuzish uchun qulay bo`lgan vosita
bo`lib, kompyuterda dastur yaratish ishlarini avtomatlashtiradi, xatoliklarni kamaytira
di va dastur tuzuvchi mehnatini yengillashtiradi. C++ dasturlash tilida massivlarning
ishlatilishi boshqa dasturlash tillariga qaraganda bir muncha afzalliklarga ega.
Massivlar bilan ishlash bazi hisoblash masalalarida ancha qulayliklar tug`diradi.
Ularning xotirada egallaydigan joyini hisobga olsak dasturning ishlash tezligi xam bir
necha marta ortadi.
Men bu kurs ishimda shuni yoritib berganmanki , massivlar xaqida umumiy
ma`lumot (bir o`lchamli va ko`p o`lchamli), ularning xotiradan egallaydigan tartibi,
saralash, tartiblash, funksiyalar bilan bog`lash , dasturlarda foydalanish kabi
yechimlariga oid turli masalalarni misollar yordamida yoritib chiqdim.Shunday
holatlar bo'lishi mumkinki, dasturning xotiraga bo'lgan ehtiyojini faqat ish paytida
aniqlash mumkin. Masalan, qachon kerakli xotira foydalanuvchi kiritishiga bog'liq.
Ushbu holatlarda dasturlarga xotirani dinamik ravishda ajratish kerak, buning uchun
C ++ tili new () va delete () operatorlarini birlashtiradi. Dinamik xotira new ()
operatori yordamida ajratiladi. new () dan keyin ma'lumotlar turini aniqlovchi va agar
bir nechta elementlar ketma-ketligi zarur bo'lsa, ularning soni qavs ichida [] bo'ladi.
U ko'rsatgichni ajratilgan yangi xotira blokining boshiga qaytaradi. Dinamik massiv
odatda eng yaxshi tanlovdir.
37](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_37.png)
![FOYDALANILGAN ADABIYOTLAR
1. Narasimha Karumanchi - Data structures and algorithms made easy Copyright
©2010 by CareerMonk.com All rights reserved.
2. Big C++ - Wiley India
3. C++: The Complete Reference- Schildt, McGraw-Hill Education (India)
4. C++ and Object Oriented Programming – Jana, PHI Learning.
5. Object Oriented Programming with C++ - Rajiv Sahay, Oxford
6. Mastering C++ - Venugopal, McGraw-Hill Educa-tion (India)
7. Vanderbilt universiteti www.dre.vanderbilt.edu/ schmidt / (615) 343-8197
8. Dr. Subasish Mohapatra . Object Oriented Pro-gramming Using C++
9. The C++ Standard Library A Tutorial and Reference by Nicolai M. Josuttis
38](/data/documents/6fed6788-c0b5-4e19-a828-065e6416a1b8/page_38.png)
Dinamik massivlarni yaratish asoslari MUNDARIJA KIRISH .......................................................................................................................................................... 2 1.Dinamik massiv ......................................................................................................................................... 3 Dinamik massiv, shuningdek, o'lchamlarini o'zgartiradigan massiv sifatida ham tanilgan, bu ish vaqtida uning imkoniyatlarini moslashuvchan o'lchamlarini o'zgartirishga imkon beradigan ma'lumotlar tuzilishi. O'zgartirib bo'lmaydigan sobit o'lchamga ega bo'lgan statik massivlardan farqli o'laroq, dinamik massivlar kerak bo'lganda o'sishi yoki kichrayishi mumkin. ......................................................................... 3 Dasturlashda dinamik massivlar odatda saqlanadigan ma'lumotlarning aniq hajmi noma'lum bo'lganda yoki vaqt o'tishi bilan o'zgarishi mumkin bo'lganda ishlatiladi. Ushbu massivlar xotirani dinamik ravishda ajratadi va ko'proq elementlarni qo'shish yoki mavjud elementlarni olib tashlash kerak bo'lganda o'lchamlarini o'zgartirish mumkin. .............................................................................................................. 3 O'lchamini o'zgartirish jarayoni odatda yangi, kattaroq xotira blokini ajratishni, unga mavjud elementlarni nusxalashni va eski xotira blokini taqsimlashni o'z ichiga oladi. Bu dinamik massivga xotirani isrof qilmasdan ko'proq elementlarni joylashtirishga imkon beradi. Aksincha, agar elementlar olib tashlansa, xotirani tejash uchun massiv qisqarishi mumkin. ....................................................................... 3 Dinamik massivlar statik massivlarga o'xshash samarali tasodifiy kirishning afzalliklarini taklif qiladi, shu bilan birga dinamik o'lchamlarning moslashuvchanligini ta'minlaydi. Biroq, o'lchamlarni o'zgartirish operatsiyalari vaqt jihatidan nisbatan qimmatga tushishi mumkin, chunki xotirani qayta taqsimlash va nusxalash ishtirok etadi. .............................................................................................................................. 3 1.1. Dinamik massivlarni yaratish. ............................................................................................................... 5 1.2. Ko'p o'lchovli massivlar. ........................................................................................................................ 8 2. Ob'ektni dinamik massivga qo'shish va o’chirish ................................................................................... 15 2.1. Dinamik massivdan olib tashlash. ....................................................................................................... 16 2.2. Dinamik massiv uchun oddiy kod. ....................................................................................................... 18 3. Ma'lumotlar tuzilmalari ......................................................................................................................... 26 4. Dinamik massivlarning ishlashiga ta'sir qiluvchi omillar ......................................................................... 33 XULOSA ..................................................................................................................................................... 37 FOYDALANILGAN ADABIYOTLAR ................................................................................................................ 38 1
KIRISH Dinamik massivlar birinchi marta kompyuter dasturlashda ma'lumotlar tuzilishi tushunchasi sifatida kiritilgan. Ularning yaratilishining aniq tarixi har xil bo'lishi mumkin, ammo ularning rivojlanishini dasturlash tillari va xotirani boshqarish texnikasidagi yutuqlar bilan bog'lash mumkin. Dasturlashning dastlabki kunlarida odatda ma'lumotlarni saqlash va boshqarish uchun sobit o'lchamdagi massivlar ishlatilgan. Biroq, sobit o'lchamdagi massivlarning cheklanishi ishlab chiquvchilar turli xil ma'lumotlarni joylashtirish uchun zarur bo'lganda yoki dasturni bajarish paytida massivning hajmi dinamik ravishda o'zgarishi uchun zarur bo'lganda aniq bo'ldi. Ushbu muammoning echimi sifatida dinamik massivlar tushunchasi paydo bo'ldi. Belgilangan hajmdagi xotirani ajratish o'rniga, dinamik massivlar haqiqiy hajm talablari asosida ish vaqtida xotirani ajratish va qayta taqsimlashga imkon beradi. Massiv hajmini oshirish kerak bo'lganda, dinamik massiv kattaroq xotira blokini ajratadi va mavjud ma'lumotlarni yangi xotira maydoniga ko'chiradi. Xuddi shunday, massiv hajmini kamaytirish kerak bo'lganda, massiv kichikroq xotira blokini qayta taqsimlashi va shunga mos ravishda sozlashi mumkin. Dinamik massivlarni amalga oshirish va qo'llab- quvvatlash yillar davomida turli dasturlash tillariga birlashtirilgan. Masalan, C++ da dinamik massivlar odatda "yangi" kalit so'z yordamida yaratiladi va ko'rsatkichlar bilan boshqariladi. Python kabi boshqa tillar avtomatik ravishda xotirani ajratish va dinamik massivlar uchun qayta taqsimlashni ro'yxatlar kabi 2
o'zlarining mahalliy ma'lumotlar tuzilmalari orqali boshqaradi. Umuman olganda, dinamik massivlarning yaratilishi va evolyutsiyasi dasturlash tillarida moslashuvchan ma'lumotlar tuzilmalariga bo'lgan ehtiyoj bilan bog'liq bo'lib, ishlab chiquvchilarga dasturni bajarish paytida turli xil ma'lumotlarni samarali boshqarish va boshqarish imkoniyatini beradi. 1.Dinamik massiv Dinamik massiv, shuningdek, o'lchamlarini o'zgartiradigan massiv sifatida ham tanilgan, bu ish vaqtida uning imkoniyatlarini moslashuvchan o'lchamlarini o'zgartirishga imkon beradigan ma'lumotlar tuzilishi. O'zgartirib bo'lmaydigan sobit o'lchamga ega bo'lgan statik massivlardan farqli o'laroq, dinamik massivlar kerak bo'lganda o'sishi yoki kichrayishi mumkin. Dasturlashda dinamik massivlar odatda saqlanadigan ma'lumotlarning aniq hajmi noma'lum bo'lganda yoki vaqt o'tishi bilan o'zgarishi mumkin bo'lganda ishlatiladi. Ushbu massivlar xotirani dinamik ravishda ajratadi va ko'proq elementlarni qo'shish yoki mavjud elementlarni olib tashlash kerak bo'lganda o'lchamlarini o'zgartirish mumkin. O'lchamini o'zgartirish jarayoni odatda yangi, kattaroq xotira blokini ajratishni, unga mavjud elementlarni nusxalashni va eski xotira blokini taqsimlashni o'z ichiga oladi. Bu dinamik massivga xotirani isrof qilmasdan ko'proq elementlarni joylashtirishga imkon beradi. Aksincha, agar elementlar olib tashlansa, xotirani tejash uchun massiv qisqarishi mumkin. Dinamik massivlar statik massivlarga o'xshash samarali tasodifiy kirishning afzalliklarini taklif qiladi, shu bilan birga dinamik o'lchamlarning moslashuvchanligini ta'minlaydi. Biroq, o'lchamlarni o'zgartirish operatsiyalari vaqt jihatidan nisbatan qimmatga tushishi mumkin, chunki xotirani qayta taqsimlash va nusxalash ishtirok etadi. 3
Dinamik massivlar dasturlash tillarida massiv hajmini kompilyatsiya vaqtida emas, balki ish vaqtida aniqlash kerak bo'lgan vaziyatlarni boshqarish uchun ishlatiladi. Dinamik massivlar uchun bir nechta umumiy foydalanish holatlari: 1. Dinamik xotirani taqsimlash: dinamik massivlar ish vaqtida massiv uchun xotirani ajratishga imkon beradi, bu massiv hajmi oldindan ma'lum bo'lmaganda yoki dasturni bajarish paytida o'zgarishi mumkin bo'lganda foydali bo'lishi mumkin. Bu odatda C/C++ da `malloc()` yoki C++ yoki Java kabi tillarda `new` operatori kabi funktsiyalar yordamida amalga oshiriladi. 2. Moslashuvchan ma'lumotlar tuzilmalari: dinamik massivlar ko'pincha ro'yxatlar, stacklar, navbatlar va vektorlar kabi dinamik ma'lumotlar tuzilmalarini amalga oshirish uchun ishlatiladi. Dinamik massivlar yordamida siz kerak bo'lganda elementlarni osongina qo'shishingiz yoki olib tashlashingiz mumkin, bu esa ma'lumotlarni samarali o'lchamlarini va manipulyatsiyasini ta'minlaydi. 3. Katta ma'lumotlar bilan ishlash: agar sizda dastlab xotiraga sig'maydigan juda katta ma'lumotlar to'plamlari bo'lsa, dinamik massivlar ma'lumotlarning bir qismini dinamik ravishda yuklash va boshqarish uchun ishlatilishi mumkin. Bu katta ma'lumotlar to'plamlarini samarali qayta ishlash va manipulyatsiya qilish imkonini beradi, chunki siz bir vaqtning o'zida ma'lumotlarning qismlarini yuklashingiz va qayta ishlashingiz mumkin. 4. Resizable konteynerlarini amalga oshirish: dinamik massivlar odatda Java-dagi ArrayList yoki C++ - dagi vektor kabi o'lchamli konteynerlar uchun asosiy ma'lumotlar tuzilishi sifatida ishlatiladi. Ushbu konteynerlar elementlar qo'shilishi yoki olib tashlanishi bilan massivning hajmini dinamik ravishda o'zgartirish imkoniyatini beradi, bu ularni ma'lumotlar to'plamlarini boshqarish uchun foydali qiladi. Umuman olganda, dinamik massivlar dasturni bajarish paytida massiv hajmi dinamik ravishda o'zgarishi kerak bo'lgan stsenariylarda moslashuvchanlikni ta'minlaydi. 4
1.1. Dinamik massivlarni yaratish. C++ tilidagi individual dinamik ob'ektlardan tashqari biz dinamik massivlardan ham foydalanishimiz mumkin. Dinamik massivda xotirani ajratish uchun new operatori ham ishlatiladi , shundan so'ng kvadrat qavs ichida massivda nechta ob'ekt bo'lishi ko'rsatiladi: int *numbers {new int[4]}; // 4 ta elementdan iborat massiv // yoki // int *numbers = new int[4]; Bundan tashqari, bu holda, yangi operator int tipidagi ob'ektga ko'rsatgichni qaytaradi - yaratilgan massivning birinchi elementi. Bunday holda, to'rtta int elementli massiv aniqlanadi, lekin ularning har biri aniqlanmagan qiymatga ega. Biroq, biz qiymatlar bilan massivni ishga tushirishimiz ham mumkin: int *numbers1 {new int[4]{}}; // massiv elementlari 0, 0, 0, 0 int *numbers2 {new int[4]{ 1, 2, 3, 4 }}; // massiv elementlari 1, 2, 3, 4 int *numbers3 {new int[4]{ 1, 2 }}; // massiv elementlari 1, 2, 0, 0 // o'xshash massiv ta'riflari // int *numbers1 = new int[4]{}; // massiv elementlari 0, 0, 0, 0 // int *numbers1 = new int[4](); // massiv elementlari 0, 0, 0, 0 // int *numbers2 = new int[4]{ 1, 2, 3, 4 }; // massiv elementlari 1, 2, 3, 4 // int *numbers3 = new int[4]{ 1, 2 }; // massiv elementlari 1, 2, 0, 0 Muayyan qiymatlar bilan massivni ishga tushirishda shuni yodda tutingki, agar figurali qavslarda massiv uzunligidan ko'proq qiymatlar bo'lsa, yangi operator ishlamay qoladi va massivni yarata olmaydi. Agar aksincha, kamroq qiymatlar 5