ওভারভিউ থেকে আপনি এ deque
হিসাবে ভাবতে পারেনdouble-ended queue
Datas মধ্যে deque
সংশোধন করা হয়েছে আকার ভেক্টরের chuncks দ্বারা সঞ্চিত হয়, যা
একটি দ্বারা নির্দেশিত map
(যা ভেক্টরের একটি অংশও তবে এর আকার পরিবর্তন হতে পারে)
এর মূল অংশের কোডটি deque iterator
নীচে রয়েছে:
/*
buff_size is the length of the chunk
*/
template <class T, size_t buff_size>
struct __deque_iterator{
typedef __deque_iterator<T, buff_size> iterator;
typedef T** map_pointer;
// pointer to the chunk
T* cur;
T* first; // the begin of the chunk
T* last; // the end of the chunk
//because the pointer may skip to other chunk
//so this pointer to the map
map_pointer node; // pointer to the map
}
এর মূল অংশের কোডটি deque
নীচে রয়েছে:
/*
buff_size is the length of the chunk
*/
template<typename T, size_t buff_size = 0>
class deque{
public:
typedef T value_type;
typedef T& reference;
typedef T* pointer;
typedef __deque_iterator<T, buff_size> iterator;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
protected:
typedef pointer* map_pointer;
// allocate memory for the chunk
typedef allocator<value_type> dataAllocator;
// allocate memory for map
typedef allocator<pointer> mapAllocator;
private:
//data members
iterator start;
iterator finish;
map_pointer map;
size_type map_size;
}
নীচে আমি আপনাকে deque
মূলত তিনটি অংশের মূল কোড দেব :
পুনরুক্তিকারীর
কীভাবে নির্মাণ করবেন deque
1. পুনরুক্তি ( __deque_iterator
)
পুনরুদ্ধারের প্রধান সমস্যাটি হ'ল, যখন ++, - পুনরুক্তিকারী, এটি অন্যান্য অংশে এড়িয়ে যেতে পারে (যদি এটি খণ্ডের প্রান্তে নির্দেশ করে)। উদাহরণস্বরূপ, সেখানে তিন ডেটা খন্ডে আছেন: chunk 1
, chunk 2
, chunk 3
।
pointer1
পয়েন্টার শুরু chunk 2
, যখন অপারেটর --pointer
এটা শেষে পয়েন্টার হবে chunk 1
তাই হিসাবে, pointer2
।
নীচে আমি এর মূল কাজটি দেব __deque_iterator
:
প্রথমত, যে কোনও অংশে এড়িয়ে যান:
void set_node(map_pointer new_node){
node = new_node;
first = *new_node;
last = first + chunk_size();
}
দ্রষ্টব্য, chunk_size()
ফাংশন যা খণ্ড আকার গণনা করে, আপনি ভাবতে পারেন এটি এখানে সরলকরণের জন্য 8 প্রদান করে।
operator*
খণ্ডে তথ্য পেতে
reference operator*()const{
return *cur;
}
operator++, --
// ইনক্রিমেন্ট উপসর্গ ফর্ম
self& operator++(){
++cur;
if (cur == last){ //if it reach the end of the chunk
set_node(node + 1);//skip to the next chunk
cur = first;
}
return *this;
}
// postfix forms of increment
self operator++(int){
self tmp = *this;
++*this;//invoke prefix ++
return tmp;
}
self& operator--(){
if(cur == first){ // if it pointer to the begin of the chunk
set_node(node - 1);//skip to the prev chunk
cur = last;
}
--cur;
return *this;
}
self operator--(int){
self tmp = *this;
--*this;
return tmp;
}
পুনরুদ্ধারকারী এন পদক্ষেপ / এলোমেলো অ্যাক্সেস এড়িয়ে যান
self& operator+=(difference_type n){ // n can be postive or negative
difference_type offset = n + (cur - first);
if(offset >=0 && offset < difference_type(buffer_size())){
// in the same chunk
cur += n;
}else{//not in the same chunk
difference_type node_offset;
if (offset > 0){
node_offset = offset / difference_type(chunk_size());
}else{
node_offset = -((-offset - 1) / difference_type(chunk_size())) - 1 ;
}
// skip to the new chunk
set_node(node + node_offset);
// set new cur
cur = first + (offset - node_offset * chunk_size());
}
return *this;
}
// skip n steps
self operator+(difference_type n)const{
self tmp = *this;
return tmp+= n; //reuse operator +=
}
self& operator-=(difference_type n){
return *this += -n; //reuse operator +=
}
self operator-(difference_type n)const{
self tmp = *this;
return tmp -= n; //reuse operator +=
}
// random access (iterator can skip n steps)
// invoke operator + ,operator *
reference operator[](difference_type n)const{
return *(*this + n);
}
2. কীভাবে নির্মাণ করবেন deque
সাধারণ ফাংশন deque
iterator begin(){return start;}
iterator end(){return finish;}
reference front(){
//invoke __deque_iterator operator*
// return start's member *cur
return *start;
}
reference back(){
// cna't use *finish
iterator tmp = finish;
--tmp;
return *tmp; //return finish's *cur
}
reference operator[](size_type n){
//random access, use __deque_iterator operator[]
return start[n];
}
template<typename T, size_t buff_size>
deque<T, buff_size>::deque(size_t n, const value_type& value){
fill_initialize(n, value);
}
template<typename T, size_t buff_size>
void deque<T, buff_size>::fill_initialize(size_t n, const value_type& value){
// allocate memory for map and chunk
// initialize pointer
create_map_and_nodes(n);
// initialize value for the chunks
for (map_pointer cur = start.node; cur < finish.node; ++cur) {
initialized_fill_n(*cur, chunk_size(), value);
}
// the end chunk may have space node, which don't need have initialize value
initialized_fill_n(finish.first, finish.cur - finish.first, value);
}
template<typename T, size_t buff_size>
void deque<T, buff_size>::create_map_and_nodes(size_t num_elements){
// the needed map node = (elements nums / chunk length) + 1
size_type num_nodes = num_elements / chunk_size() + 1;
// map node num。min num is 8 ,max num is "needed size + 2"
map_size = std::max(8, num_nodes + 2);
// allocate map array
map = mapAllocator::allocate(map_size);
// tmp_start,tmp_finish poniters to the center range of map
map_pointer tmp_start = map + (map_size - num_nodes) / 2;
map_pointer tmp_finish = tmp_start + num_nodes - 1;
// allocate memory for the chunk pointered by map node
for (map_pointer cur = tmp_start; cur <= tmp_finish; ++cur) {
*cur = dataAllocator::allocate(chunk_size());
}
// set start and end iterator
start.set_node(tmp_start);
start.cur = start.first;
finish.set_node(tmp_finish);
finish.cur = finish.first + num_elements % chunk_size();
}
ধরা যাক এর i_deque
20 টি উপাদান রয়েছে 0~19
যার খণ্ড আকার 8 এবং এখন ধাক্কা ব্যাক 3 উপাদান (0, 1, 2) থেকে i_deque
:
i_deque.push_back(0);
i_deque.push_back(1);
i_deque.push_back(2);
এটি নীচের মত অভ্যন্তরীণ কাঠামো:
তারপরে আবার পুশ_ব্যাক করুন, এটি নতুন অংশ বরাদ্দ দেবে:
push_back(3)
যদি আমরা push_front
, এটি পূর্বের আগে নতুন অংশ বরাদ্দ করা হবেstart
দ্রষ্টব্য যখন push_back
উপাদানটিকে ডীক হিসাবে তৈরি করা হয়েছে, যদি সমস্ত মানচিত্র এবং খণ্ডগুলি পূরণ করা হয় তবে এটি নতুন মানচিত্র বরাদ্দ করতে এবং খণ্ডগুলিকে সামঞ্জস্য করবে B তবে উপরের কোডটি বুঝতে আপনার পক্ষে যথেষ্ট deque
।