C++ std::deque (Ikki tomonlama navbat)
C++ da STL deque ketma-ket konteyner bo'lib, ikki tomonlama navbat ma'lumotlar strukturasining funksionalligini ta'minlaydi.
Muntazam navbatda elementlar orqa tomondan qo'shiladi va old tomondan chiqariladi. Biroq, dequeda biz old va orqa qismlarga elementlarni kiritishimiz va olib tashlashimiz mumkin.
Deque Data Structure

To learn more about deques, visit Deque Data Structure.
C++ da deque yaratish uchun avval deque sarlavha faylini kiritishimiz kerak.
#include <deque>
Ushbu faylni import qilgandan so'ng, biz quyidagi sintaksis yordamida deque yaratishimiz mumkin:
deque<type> dq;
Bu erda type biz dequeda saqlamoqchi bo'lgan ma'lumotlar turini ko'rsatadi. Masalan,
// butun sonli ma'lumotlar turini yarating
deque<int> dq_integer;
// string ma'lumotlar turini yarating
deque<string> dq_string;
Biz C++ deque-ni quyidagi usullar bilan ishga tushirishimiz mumkin:
// 1-usul: ishga tushirish ro'yxati
deque<int> deque1 = {1, 2, 3, 4, 5};
// 2-usul: bir xil ishga tushirish
deque<int> deque2 {1, 2, 3, 4, 5};
Bu erda deque1 ham, deque2 ham 1, 2, 3, 4, 5 qiymatlari bilan ishga tushiriladi.
#include <iostream>
#include <deque>
using namespace std;
// funksiya prototipi
void display_deque(deque<int>);
int main() {
// yagona ishga tushirish
deque<int> deque1 {1, 2, 3, 4, 5};
cout << "deque1 = ";
// deque1 ning ko'rsatish elementlari
for (int num : deque1) {
cout << num << ", ";
}
return 0;
}
Chiqish
deque1 = 1, 2, 3, 4, 5,
Yuqoridagi misolda biz bir xil ishga tushirish yordamida deque1 nomli dequeni e'lon qildik va ishga tushirdik.
deque<int> deque1 {1, 2, 3, 4, 5};
Keyin, biz ranged for loop yordamida deque tarkibini ko'rsatdik.
for (int num : deque1) {
cout << num << ", ";
}
C++ Deque yaratishning boshqa usullari Fill Constructor Method yordamida biz uning hajmi va elementini belgilash orqali dequeni ishga tushirishimiz mumkin. Misol uchun, // to'ldiruvchi konstruktor deque<int> deque1(5, 12); Bu yerda biz 12 qiymatli 5 o‘lchamli dekani ishga tushirdik. Bu deque<int> deque1 = {12, 12, 12, 12, 12}; ga ekvivalent. Barcha elementlar bir xil qiymatga ega ekanligiga e’tibor bering. Biz boshqa dequedan elementlarni nusxalash orqali dequeni ishga tushirishimiz mumkin. Bu diapazon usuli sifatida tanilgan. Biz diapazon usulini ishga tushirish yordamida bir dequeni boshqasiga nusxalashimiz mumkin. deque<int> deque1 = {1, 2, 3, 4, 5}; // copy all elemnts of deque1 to deque2 deque<int> deque2(deque1.begin(), deque1.end()); Bu yerda biz birinchi navbatda deque1 nomli deque yaratdik. Keyin, biz deque1 ning barcha elementlarini nusxalash orqali deque2 deb nomlangan boshqa deque yaratdik. Biz nusxa olmoqchi bo'lgan elementlar oralig'ini ham belgilashimiz mumkin. Masalan, // deque1 deque<int> deque3(deque1.begin() + 1, deque1.begin() + 3 ning 1 indeksidan 2 indeksiga elementlarni nusxalash; Bu erda boshlang'ich nuqtasi deque1.begin() + 1 bo'lib, u deque1 ning 1 indeksiga ishora qiladi. Yakuniy nuqta deque1.begin() + 3 bo'lib, u indeks 3 ga ishora qiladi. Biroq, deque3 {2, 3} bo'ladi, chunki oxirgi nuqta eksklyuziv, ya'ni oxirgi nuqta ko'chirilmaydi.
C++ tilida deque klassi dequeda turli operatsiyalarni bajarish uchun turli usullarni taqdim etadi.
Usullar tavsifi push_back() elementni orqaga qo'yadi push_front() elementni old qismiga qo'yadi pop_back() elementni orqadan olib tashlaydi pop_front() elementni old tomondan olib tashlaydi front() oldingi elementni qaytaradi back() orqadagi elementni qaytaradi at() XCODEXning ko'rsatilgan indeksidagi elementni o'rnatadi/qaytaradi XCODEX ning XCODEX raqamlarini qaytarsa, XCODEX ning XCODEX raqamlarini qaytarsa. deque bo'sh
Elementlarni kiritish uchun quyidagi usullardan foydalanishimiz mumkin:
-push_back() - oxirida elementlarni kiritish
-push_front() - elementlarni boshida kiritish
Masalan,
#include <iostream>
#include <deque>
using namespace std;
int main() {
deque<int> nums {2, 3};
cout << "Initial Deque: ";
for (const int& num : nums) {
cout << num << ", ";
}
// orqa tomonda butun son 4 qo'shing
nums.push_back(4);
// old tomoniga butun son 1 qo'shing
nums.push_front(1);
cout << "\nFinal Deque: ";
for (const int& num : nums) {
cout << num << ", ";
}
return 0;
}
Chiqish
Initial Deque: 2, 3,
Final Deque: 1, 2, 3, 4,
Yuqoridagi misolda biz deque 2 va 3 elementlari bilan nums nomli butun sonlarni ishga tushirdik.
Keyin, biz 4-sonni raqamlarning orqa tomoniga qo'ydik.
// raqamlar = {2, 3, 4}
nums.push_back(4);
Nihoyat, biz deque old tomoniga 1 qo'shdik.
// raqamlar = {1, 2, 3, 4}
nums.push_front(1);
[!NOTE] Dequega elementlar qo'shish uchun
insert()vaemplace()usullaridan ham foydalanishimiz mumkin.
deque elementlariga kirish uchun quyidagi usullardan foydalanishimiz mumkin:
-front() - oldingi elementni qaytaradi
-back() - orqadagi elementni qaytaradi
-at() - belgilangan indeksdagi elementni qaytaradi
Masalan,
#include <iostream>
#include <deque>
using namespace std;
int main() {
deque<int> nums {1, 2, 3};
cout << "Front element: " << nums.front() << endl;
cout << "Back element: " << nums.back() << endl;
cout << "Element at index 1: " << nums.at(1) << endl;
cout << "Element at index 0: " << nums[0];
return 0;
}
Chiqish
Front element: 1
Back element: 3
Element at index 1: 2
Element at index 0: 1
Yuqoridagi misolda,
-nums.front() - deque old qismidagi elementni qaytaradi, ya'ni 1
-nums.back() - dequening orqa qismidagi elementni qaytaradi, ya'ni 3
-nums.at(1) - 1-indeksdagi elementni, ya'ni 2-ni qaytaradi
-nums[0] - 0 indeksidagi elementni qaytaradi, ya'ni 1
[!NOTE] Deque elementlariga kirish uchun
[]operatoridan foydalanishimiz mumkin bo'lsa-da,at()usulidan foydalanish afzalroqdir. Buning sababi,at()deque chegaradan tashqarida bo'lganda istisno qiladi,[]esa axlat qiymatini beradi.
deque elementini o'zgartirish uchun at() usulidan foydalanishimiz mumkin. Masalan,
#include <iostream>
#include <deque>
using namespace std;
int main() {
deque<int> nums = {1, 2};
cout << "Initial Deque: ";
for (const int& num : nums) {
cout << num << ", ";
}
// indeksdagi elementlarni o'zgartirish
nums.at(0) = 3;
nums.at(1) = 4;
cout << "\nUpdated Deque: ";
for (const int& num : nums) {
cout << num << ", ";
}
return 0;
}
Chiqish
Initial Deque: 1, 2,
Updated Deque: 3, 4,
Yuqoridagi misolda nums deque ning dastlabki tarkibi {1, 2} dir.
Keyin, biz belgilangan indekslardagi elementlarni o'zgartirish uchun at() usulidan foydalandik:
-nums.at(0) = 2; - 0 indeksidagi qiymatni 3 ga o'zgartiradi
-nums.at(1) = 4; - indeks qiymatini 1 dan 4 gacha o'zgartiradi
Quyidagi usullar yordamida deque elementlarini olib tashlashimiz mumkin:
-pop_back() - elementni orqa tomondan olib tashlaydi
-pop_front() - elementni old tomondan olib tashlaydi
Masalan,
#include <iostream>
#include <deque>
using namespace std;
// display_deque() funksiyasi prototipi
void display_deque(deque<int>);
int main() {
deque<int> nums {1, 2, 3};
cout << "Initial Deque: ";
display_deque(nums);
// elementni orqa tomondan olib tashlang
nums.pop_back();
cout << "\nDeque after pop_back(): ";
display_deque(nums);
// elementni old tomondan olib tashlang
nums.pop_front();
cout << "\nDeque after pop_front(): ";
display_deque(nums);
return 0;
}
// deque elementlarini chop etish uchun yordamchi funksiya
void display_deque(deque<int> dq){
for (const int& num : dq) {
cout << num << ", ";
}
}
Chiqish
Initial Deque: 1, 2, 3,
Deque after pop_back(): 1, 2,
Deque after pop_front(): 2,
Yuqoridagi misolda biz {1, 2, 3} elementlari bilan nums nomli deque butun sonini ishga tushirdik.
Keyin raqamlardan elementlarni olib tashlash uchun pop_back() va pop_front() dan foydalandik.
nums.pop_back(); // olib tashlaydi 3
names.pop_front(); // olib tashlaydi 1
Shunday qilib, yakuniy deque {2} bo'ladi.
Iteratorlar deque elementining xotira manziliga ishora qilish uchun ishlatilishi mumkin.
Biz quyidagi sintaksis yordamida deque iteratorini yaratishimiz mumkin:
deque<type>::iterator itertaor_name;
Masalan,
// int deque uchun iterator
deque<int>::iterator iter_int;
//
deque<double>::iterator iter_double;
Biz iteratorlar yordamida deque -dagi elementlarga kirishimiz mumkin. Masalan,
#include <iostream>
#include <deque>
using namespace std;
int main() {
deque<int> nums {1, 2, 3};
// deque uchun iteratorni e'lon qiling
deque<int>::iterator dq_iter;
// iteratorni birinchi elementga ko'rsating
dq_iter = nums.begin();
// * yordamida itertor tomonidan ko'rsatilgan chop etish qiymati
int first_element = *dq_iter;
cout << "nums[0] = " << first_element << endl;
// iteratorni 1-indeksdagi elementga ko'rsating
dq_iter = nums.begin() + 1;
int element_index1 = *dq_iter;
cout << "nums[1] = " << element_index1 << endl;
// iterator nuqtasini oxirgi elementga aylantiring
dq_iter = nums.end() - 1;
int last_element = *dq_iter;
cout << "nums[2] = " << last_element;
return 0;
}
Chiqish
nums[0] = 1
nums[1] = 2
nums[2] = 3
Yuqoridagi misolda biz deque dagi elementlarga kirish uchun iteratorlardan foydalanganmiz. Dastlab, biz deque tamsayıga ishora qiladigan iterator yaratdik:
deque<int>::iterator dq_iter;
Keyin, biz quyidagi elementlarga ishora qilish uchun dq_iter iteratoridan foydalandik:
dq_iter = nums.begin();
Bu erda begin() usuli birinchi elementga ishora qiluvchi iteratorni qaytaradi.
dq_iter = nums.begin() + 1;
begin() + 1 kodi 1-indeksdagi elementga ishora qiluvchi iteratorni qaytaradi.
[!NOTE] Umumlashtirish uchun
nums.begin() + iiindeksidagi elementga ishora qiladi.
dq_iter = nums.end() - 1;
E'tibor bering, biz nums.end() o'rniga nums.end() - 1 dan foydalanmoqdamiz.
Buning sababi, end() usuli iteratori oxirgi elementdan o'tgan iteratorga ishora qiladi. Shunday qilib, yakuniy elementni olish uchun biz 1 ni ayiramiz.
Muayyan elementga ishora qilish uchun dq_iter dan foydalangandan so'ng, biz ushbu elementning qiymatini olish uchun * bilvosita operatoridan foydalanamiz:
// birinchi elementga ishora qiling
dq_iter = nums.begin();
// 1 qaytaradi
int first_element = *dq_iter;
Bu yerda *dq_iter dq_iter iteratori ko'rsatgan element qiymatini beradi.
Tez-tez so'raladigan savollar erase() usuli yordamida ko'rsatilgan indeksdagi elementni olib tashlashimiz mumkin. Masalan, deque<int> nums {1, 2, 3, 4, 5}; // removes element at index 1 // nums becomes {1, 3, 4, 5} nums.erase(nums.begin() + 1); Yuqoridagi kod 1-indeksdagi elementni nums dequedan olib tashlaydi. Shunday qilib, biz istalgan indeksdagi elementni quyidagi yordamida o'chirib tashlashimiz mumkin: nums.erase(nums.begin() + index); Biz bu erda ham erase() usulidan foydalanishimiz mumkin. #include <iostream> #include <deque> using namespace std; int main() { deque<int> nums {1, 2, 3, 4, 5}; // removes elements from index 1 to 2 nums.erase(nums.begin() + 1, nums.begin() + 3); for(auto num: nums) { cout << num << ", "; } return 0; } Chiqish 1, 4, 5, Dastlab, nums {1, 2, 3, 4, 5} elementlarini o'z ichiga oladi. Keyin 1-indeksdan 2-indeksgacha boʻlgan elementlarni nums.erase(nums.begin() + 1, nums.begin() + 3); yordamida olib tashlaymiz. Eʼtibor bering, diapazonning oxirgi nuqtasi nums.begin() + 3 , lekin 3-indeksdagi element oʻchirilmaydi. Buning sababi, erase() funksiyasining so'nggi nuqtasi eksklyuzivdir. Dequening barcha elementlarini o'chirish uchun clear() usulidan foydalanishimiz mumkin. deque<int> nums {1, 2, 3}; // clear all the elements nums.clear(); Dequedagi elementlar sonini topish uchun size() usulidan foydalanishimiz mumkin. deque<int> nums {1, 2}; // returns 2 cout << nums.size(); empty() usuli yordamida deque bo'sh yoki yo'qligini ham aniqlashimiz mumkin: // false coutni qaytaradi << nums.empty(); Ha, biz deque iteratorini ishga tushirish uchun auto kalit so'zidan foydalanishimiz mumkin. Biroq, biz auto dan iteratorni ishga tushirmasdan oddiygina e'lon qilish uchun foydalana olmaymiz. Misol uchun, bizda nums deb nomlangan int deque bor deylik. Keyin quyidagi auto dq_iter = nums.begin(); kodi deque<int>::iterator dq_iter = nums.begin(); ga ekvivalent bo'ladi Biroq, quyidagi kod noto'g'ri: auto dq_iter; // invalid Buning sababi, biz dq_iterni ishga tushirmaganmiz. Natijada, C++ uning turini aniqlay olmaydi, shuning uchun xatolik yuzaga keladi.