logo

Dinamik massivlarni yaratish asoslari

Yuklangan vaqt:

12.08.2023

Ko'chirishlar soni:

0

Hajmi:

163.7890625 KB
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 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     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 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 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 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             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 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      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 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 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 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 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 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 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         // 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                         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                 // 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                 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         }
        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         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 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 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 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 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 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 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 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 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 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 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 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 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 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

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