自定义的双端队列deque

本文详细介绍了一种自实现的双端队列(deque)数据结构,包括其内部实现机制和关键操作,如push_back、push_front、pop_back、pop_front等。通过具体的代码示例,展示了如何在C++中实现并测试这种数据结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主要用于记录一下(代码量太少,没有使用git,又担心代码丢失了),代码未必正确,请勿参考!

#ifndef MYDEQUEITERATOR_HPP_INCLUDED
#define MYDEQUEITERATOR_HPP_INCLUDED

#include<iostream>
using namespace std;

namespace com
{
namespace example
{
namespace stl
{
template<typename T>
class MyDequeIterator
{
public:
    typedef T value_type;
    typedef T& reference;
    typedef const T& const_reference;
    typedef T* pointer;
    typedef const T* const_pointer;
    typedef size_t size_type;
    typedef ptrdiff_t difference_type;
    typedef pointer* map_pointer;
    typedef MyDequeIterator self;

    #define BUFSIZE 32

public:
    /**
    * 获取缓冲区的元素个数
    * 当元素大小大于缓冲区时,该怎么处理,
    * 还是有问题的
    */
    size_type get_element_count(){
        size_type ele_size = sizeof(T);
        if(ele_size < BUFSIZE){
            return BUFSIZE / ele_size;
        }else{
            return 1;
        }
    }

    /**
    * 跳转到控制中心的下一个node
    */
    void goToNextNode(){
        this->node += 1;
        this->start = *(this->node);
        this->end = this->start + get_element_count();
		this->cur = this->start;
    }

    /**
    * 跳转到控制中心的前一个node
    */
    void goToPreviousNode(){
        this->node -= 1;
        this->start = *(this->node);
        this->end = this->start + get_element_count();
		this->cur = this->end - 1;
    }


public:
    /**
    * 设置控制中心的node
    */
    void setNode(map_pointer node){
        this->node = node;
        this->start = *(this->node);
        this->end = this->start + get_element_count();
    }

public:
    /**
    * 前置++
    */
    self& operator++(){
        if(this->cur >= this->end - 1){
            goToNextNode();
        }else{
            this->cur++;
        }
        return *this;
    }

    /**
    * 后置++
    */
    self operator++(int){
        self tmp = *this;
        ++(*this);
        return tmp;
    }

    /**
    * 前置--
    */
    self& operator--(){
        if(this->cur <= this->start){
            goToPreviousNode();
        }else{
            this->cur--;
        }
        return *this;
    }

    /**
    * 后置--
    */
    self operator--(int){
        self tmp = *this;
        --(*this);
        return tmp;
    }

    reference operator*(){
        return *(this->cur);
    }

    bool operator==(self& other){
        return this->node == other.node && this->cur == other.cur;
    }

    bool operator!=(self& other){
        return this->node != other.node || this->cur != other.cur;
    }

    /**
    * 最关键的一个方法,实现随机访问的功能
    */
    self& operator+=(difference_type diff){
        size_type ele_count = get_element_count();//每个缓冲区的元素个数
        difference_type offset = this->cur - this->start + diff;//相对某个特定缓冲区头部的偏移
        if(offset >= 0){
            if(offset < ele_count){
                this->cur += diff;
            }else{
                size_type node_offset = offset / ele_count + 1;
                size_type end_offset = offset % ele_count;
                this->node += node_offset;
                setNode(this->node);
                this->cur = this->start + end_offset - 1;//设置指向缓冲区的当前位置
            }
        }else{
            size_type node_offset = -offset / ele_count + 1;
            size_type end_offset = -offset % ele_count;
            this->node -= node_offset;
            setNode(this->node);
            this->cur = this->end - end_offset;//设置指向缓冲区的当前位置
        }
        return *this;
    }

    self operator+(difference_type diff){
        self tmp = *this;
        tmp += diff;
        return tmp;
    }

    self& operator-=(difference_type diff){
        return (*this) += (-diff);
    }

    self operator-(difference_type diff){
        self tmp = *this;
        tmp -= diff;
        return tmp;
    }

    self& operator[](size_type index){
        return *this += index;
    }

public:
    map_pointer node;//指向控制中心的指针
    pointer start;//指向某个缓冲区的开始
    pointer end;//指向某个缓冲区的尾部 + 1
    pointer cur;//指向某个缓冲区的当前位置
};//end MyDequeIterator

}//end namespace stl
}//end namespace example
}//end namespace com



#endif // MYDEQUEITERATOR_HPP_INCLUDED

 

#ifndef MYDEQUE_HPP_INCLUDED
#define MYDEQUE_HPP_INCLUDED

#include "com/example/stl/MyDequeIterator.hpp"
#include <cstdlib>
#include <new>

namespace com
{
namespace example
{
namespace stl
{
template<typename T, typename Alloc = std::allocator<T>>
class MyDeque{
public:
    typedef T value_type;
    typedef T& reference;
    typedef const T& const_reference;
    typedef T* pointer;
    typedef const T* const_pointer;
    typedef size_t size_type;
    typedef ptrdiff_t difference_type;
    typedef pointer* map_pointer;
    typedef MyDequeIterator<T> iterator;
    typedef std::allocator<T> data_allocator_type;
    typedef std::allocator<pointer> control_allocator_type;
    #define BUFSIZE 32

private:
	/**
	* len指的是元素个数,BUFSIZE指的是缓冲区大小
	*/
    MyDeque(size_type len){
        this->len = len;
        size_type node_count = this->len * sizeof(value_type) / BUFSIZE + 1;
        this->control_len = 2 * node_count;//控制中心的大小是所需要的大小的2倍
        //为控制中心分配空间
        pcontrol = control_allocator.allocate(this->control_len * sizeof(pointer));

        //给start迭代器和end迭代器设置初值
        start.node = pcontrol + this->control_len / 4;
        end_1.node = start.node + node_count - 1;

		//start迭代器和end迭代器之间的缓冲区分配空间(注意这一块逻辑的位置)
		size_type ele_count = start.get_element_count();
        for(map_pointer p = start.node; p <= end_1.node; p++){
            *p = data_allocator.allocate(sizeof(value_type) * ele_count);
        }

		//给start迭代器和end迭代器设置初值
		start.setNode(start.node);
		end_1.setNode(end_1.node);
		start.cur = start.end;
		end_1.cur = end_1.start - 1;//注意这个地方的设置
    }

public:
    MyDeque(){
        //MyDeque(0);//错误的,构造函数不能这样调用
		new(this) MyDeque(4);
    }

private:
    /**
    * end迭代器是否到了控制中心的边界了
    */
    bool is_end_boundary_control(){
        return (end_1.node == (pcontrol + control_len - 1)) && (end_1.cur == (end_1.end - 1));
    }

    /**
    * start迭代器是否到了控制中心的边界了
    */
    bool is_start_boundary_control(){
        return (start.node == pcontrol) && (start.cur == start.start);
    }

    /**
    * 给控制中心扩容
    */
    void expan_control(){
		size_type tmp_len = this->control_len;//老的长度
		map_pointer old_start_node = start.node;//老的start
		map_pointer old_end_node = end_1.node;//老的end
		map_pointer delete_point = this->pcontrol;//专门用于删除的
		size_type start_end_offset = end_1.node - start.node;//开始和结尾之间的偏移
        this->control_len = this->control_len * 2;
        this->pcontrol = control_allocator.allocate(sizeof(pointer) * this->control_len);
        //将老的复制到新的里面
        size_type base_index = this->control_len / 4;
        map_pointer tmp_after_pointer = this->pcontrol + base_index;
		while(old_start_node <= old_end_node){
			*tmp_after_pointer = *old_start_node;
			++tmp_after_pointer;
			++old_start_node;
		}
        //给迭代器重新赋值
        start.node = this->pcontrol + base_index;//注意这个地方的计算
        end_1.node = start.node + start_end_offset;
        //释放老的控制中心所占的空间
		control_allocator.deallocate(delete_point, sizeof(pointer) * tmp_len);
    }

    /**
    * 在最后一位重新分配空间,然后插入元素
    */
    void allocate_and_insert_last(reference obj){
        size_type ele_count = end_1.get_element_count();
        *(++end_1.node) = data_allocator.allocate(sizeof(value_type) * ele_count);
        end_1.start = *(end_1.node);
        end_1.end = end_1.start + ele_count;
        end_1.cur = end_1.start;
        new(end_1.cur) value_type(obj);//调用copy构造函数
    }

    /**
    * 在开始一位重新分配空间,然后插入元素
    */
    void allocate_and_insert_start(reference obj){
        size_type ele_count = start.get_element_count();
        *(--start.node) = data_allocator.allocate(sizeof(value_type) * ele_count);
        start.start = *(start.node);
        start.end = start.start + ele_count;
        start.cur = start.end - 1;
        new(start.cur) value_type(obj);
    }

public:
    /**
    * 从后面插入一个元素
    */
    void push_back(reference obj){
        if(is_end_boundary_control()){
        //需要对控制中心扩容
        expan_control();
        allocate_and_insert_last(obj);
        }else{
			++(end_1.cur);
            if(end_1.cur < end_1.end){
                new(end_1.cur) value_type(obj);//调用copy构造函数
            }else{
                allocate_and_insert_last(obj);
            }
        }
        this->len++;//长度增加
    }

    /**
    * 弹出最后一个元素
    */
    value_type pop_back(){
        value_type tmp = *(end_1.cur);
        --end_1;
        this->len--;
        return tmp;
    }

    /**
    * 返回最后一个元素,不弹出
    */
    reference back(){
        return *(end_1.cur);
    }

    /**
    * 从容器的前面插入元素
    */
    void push_front(reference obj){
        if(is_start_boundary_control()){
            //需要扩容
            expan_control();
            allocate_and_insert_start(obj);
        }else{
            --start.cur;
            if(start.cur < start.start){
                allocate_and_insert_start(obj);
            }else{
                new(start.cur) value_type(obj);//调用copy构造函数
            }

        }
        this->len++;
    }


    /**
    * 从容器的前面弹出元素
    */
    value_type pop_front(){
        value_type tmp = *(start.cur);
        ++start;
        this->len--;
        return tmp;
    }

    /**
    * 返回最前面的元素
    */
    reference front(){
        return *(start.cur);
    }

    /**
    * 清空容器
    */
    void clear(){	
        map_pointer start_node = start.node;
		map_pointer end_node = end_1.node;
		size_type arr_len = end_node - start_node + 1;
		map_pointer* arr = new map_pointer[arr_len];
        size_type ele_count = start.get_element_count();
		//销毁容器里面的对象
		for(int i = 0; i < arr_len; i++){
			arr[i] = start_node + i;
		}
		for(int i = 0; i < arr_len; i++){
			for(int j = 0; j < ele_count; j++){
				data_allocator.destroy(*arr[i] + j);
			}
			data_allocator.deallocate(*arr[i], ele_count * sizeof(value_type));
		}
		//销毁控制中心
		control_allocator.deallocate(this->pcontrol, sizeof(pointer) * this->control_len);
		delete[] arr;
        this->len = 0;
		new(this) MyDeque(0);
    }



public:
    iterator begin(){
        return this->start;
    }

    iterator end_my(){
        return this->end_1;
    }

    size_type size(){
        return this->len;
    }

    bool empty(){
        return this->len == 0;
    }

private:
    iterator start;
    iterator end_1;
    //指向控制中心的开始
    //pcontrol + control_len就是控制中心的尾部
    map_pointer pcontrol;
    size_type control_len;//控制中心的大小
    size_type len;
    data_allocator_type data_allocator;
    control_allocator_type control_allocator;


};//end MyDeque
}//end namespace stl
}//end namespace example
}//end namespace com


#endif // MYDEQUE_HPP_INCLUDED

 

// TestSTL.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "com/example/stl/MyDeque.hpp"
#include<iostream>

using namespace com::example::stl;
using namespace std;

class Object{
public:
	Object(int x, float y){
		this->x = x;
		this->y = y;
	}

	Object(){

	}

	~Object(){
		//cout << "~Object 析构..." << endl;
	}
public:
	int x;
	float y;

public:
	void toString(){
		cout << "x = " << x << ", " << "y = " << y << endl;
	}
};

void test1(){
	MyDeque<Object> dq;
	int len = 25;
	for(int i = 0; i < len; i++){
		Object obj(i, i);
		dq.push_back(obj);
	}

	cout << "插入完成..........................." << endl;
	cout << endl;

	cout << "开始调用pop_back()..........................." << endl;
	//测试pop_back()
	for(int i = 0; i < len; i++){
		dq.pop_back().toString();
	}

	cout << "开始调用clear()..........................." << endl;
	dq.clear();
}

void test2(){
	MyDeque<Object> dq;
	int len = 25;
	for(int i = 0; i < len; i++){
		Object obj(i, i);
		dq.push_front(obj);
	}
	
	//测试pop_front()
	for(int i = 0; i < len; i++){
		dq.pop_front().toString();
	}

	cout << "开始调用clear()..........................." << endl;
	dq.clear();
}

void test3(){
	MyDeque<int> dq;
	int len = 25;
	int tmp;
	for(int i = 0; i < len; i++){
		tmp = i;
		dq.push_front(tmp);
	}
	
	//测试pop_front()
	for(int i = 0; i < len; i++){
		cout << dq.pop_front() << endl;
	}

	dq.clear();
}

void test4(){
	MyDeque<float> dq;
	int len = 700;
	float tmp;
	for(int i = 0; i < len; i++){
		tmp = i * 0.1f;
		dq.push_front(tmp);
	}
	
	//测试pop_front()
	for(int i = 0; i < len; i++){
		cout << dq.pop_front() << endl;
	}
}


void test5(){
	typedef MyDeque<Object>::iterator iterator_;
	MyDeque<Object> dq;
	int len = 800;
	for(int i = 0; i < len; i++){
		Object obj(i, i);
		dq.push_back(obj);
		dq.push_front(obj);
	}
	//相等的时候也要打印出来
	iterator_ it = dq.begin();
	for(; it != dq.end_my(); ++it){
		(*it).toString();
	}
	(*it).toString();
}

int main(int argc, _TCHAR* argv[])
{
	test5();
	system("pause");
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值