用C++语言实现双端队列

1.目的

基于双链表实现双端队列的典型操作(判空、头插、头删、尾插、尾删、普通构造、拷
贝构造、赋值运算符重 载、析构)

2.原理
双端队列头插:
在这里插入图片描述
双端队列尾插:

在这里插入图片描述在这里插入图片描述
双端队列头删:
在这里插入图片描述
双端队列尾删:
在这里插入图片描述
3.代码
dlist.cpp

#include <iostream>

using namespace std;


template <typename T>
class Dlist {
public:
bool isEmpty() const;  //判空
void insertFront(T *o); //在表头插入元素
void insertBack(T *o);  //在表尾插入元素
T *removeFront(); //删除一个表头元素
T *removeBack();  //删除一个表尾元素
Dlist();  //构造函数
Dlist(const Dlist &l); //拷贝构造函数
Dlist& operator=(const Dlist &l); //"="运算符重载
~Dlist();  //析构函数
private:
struct Node {
    Node(){  //给指针赋初始值
        this->next = NULL;
        this->prev = NULL;
        this->o = NULL;
    }
Node *next; //指向下一个节点
Node *prev; //指向前一个节点
T *o;
};
Node *first;  //指向表头
Node *last;   //指向表尾
void makeEmpty(); //建立一个空表
void removeAll(); //删除表中所有元素
void copyAll(const Dlist &l); //将l表中的元素值拷贝到当前表
};

template <typename T>
bool Dlist<T>::isEmpty() const  //判空
{
    return first == NULL;
}

template <typename T>
void Dlist<T>::insertFront(T *o) //在表头插入元素
{
    Node *new_node = new Node(); //定义一个新的节点

    new_node->o = o;  //给新节点赋初值,将要插入的值放入新节点
    if(first == NULL) //当原表为空时,表明要插入的节点为表头
    {
        first = last = new_node;
    }
    else{ //当原表不为空
        first->prev = new_node; //将原表头的前指针指向新节点
        new_node->next = first; //将新节点的后指针指向原表头
        first = new_node; //让表头指向新节点
    }
}

template <typename T>
void Dlist<T>::insertBack(T *o) //在表尾插入元素
{
    Node *new_node = new Node(); //定义一个新的节点

    new_node->o = o;  //给新节点赋初值,将要插入的值放入新节点
    if(first == NULL) //当原表为空时,表明要插入的节点为表头
    {
        first = last = new_node;
    }
    else{ //当原表不为空
        last->next = new_node; //将原表尾的后指针指向新节点
        new_node->prev = last; //将新节点的前指针指向原表尾
        last = new_node; //让表尾指向新节点
    }
}

template <typename T>
T* Dlist<T>::removeFront() //删除一个表头元素
{
    Node *new_node = NULL; //定义一个新的节点
    T* p;

    if(NULL == first)
        return NULL; //如果表是空的则返回空
    new_node = first; //让新指针指向表头
    p = new_node->o; //保存表头元素值
    first = first->next; //表头向后移一位
    if(NULL != first)
    {
        first->prev = NULL; //新的表头的前指针置空
    }
    else{
        first = NULL;  //如果表中无元素,将表头置空
    }
    delete new_node; //删除原表头

    return p;
}

template <typename T>
T* Dlist<T>::removeBack() //删除一个表尾元素
{
    Node *new_node = NULL; //定义一个新的节点
    T* p = NULL;
    if(NULL == first)
       {
           return NULL;//如果表是空的则返回空
       }
    new_node = last; //让新指针指向表尾
    p = last->o; //保存表尾元素值
    last = last->prev; //表尾向前移一位
    if(last != NULL) //如果表尾前还有元素
    {
        last->next = NULL; //新的表尾的后指针置空
    }
    else{
        first = NULL; //如果表中无元素,将表头置空
    }
    delete new_node; //删除原表尾
    return p;
}

template <typename T>
Dlist<T>::Dlist() //构造函数
{
    makeEmpty();  //建立一个空表
}

template <typename T>
Dlist<T>::Dlist(const Dlist &l) //拷贝构造函数
{
    makeEmpty(); //建立一个空表
    copyAll(l);  //将l表元素复制到当前表
}

template <typename T>
Dlist<T>& Dlist<T>::operator=(const Dlist &l)  //"="运算符重载
{
    Dlist new_copy(l); //调用拷贝构造函数,将l表元素拷贝给new_copy
    removeAll(); //删除原表中所有元素
    first = new_copy.first; //让当前表的头指针指向new_copy的头指针
    last = new_copy.last; //让当前表的尾指针指向new_copy的尾指针
    new_copy.first = NULL;
    new_copy.last = NULL;
    return *this; //返回当前表
}

template <typename T>
Dlist<T>::~Dlist()  //析构函数
{
    if( !isEmpty() ){  //当表不为空时删除所有元素
		removeAll();
	}
}

template <typename T>
void Dlist<T>::makeEmpty()  //建立一个空表
{
    first = NULL;  //初始化指向表头的指针
    last = NULL;   //初始化指向表尾的指针
}

template <typename T>
void Dlist<T>::removeAll() //删除表中所有元素
{
    Node *p = NULL;
	while(first != NULL){ //遍历当前表,逐个删除
		p = first;
		first = first->next;
		delete p;
	}
}

template <typename T>
void Dlist<T>::copyAll(const Dlist &l) //将l表中的元素值拷贝到当前表
{
    Node *old_node = NULL; //定义指针指向要拷贝的表
    old_node = l.first; //指向要拷贝的表的表头
    while(old_node != NULL) //当要拷贝的表有元素时拷贝
    {
        insertBack(old_node->o);//将元素依次从后面插入当前表中
        old_node = old_node->next;
    }
}

测试类 distmain.cpp

#include <iostream>
#include "dlist.cpp"

using namespace std;

int main()
{
    Dlist<int> ilist;
    Dlist<int> one;
    int *ip = new int(3);
    int *j = new int(5);
    int *i = new int (7);
    int *p = new int();
    ilist.insertFront(ip);  //3
    ilist.insertFront(j);   //5 3
    ilist.insertBack(i);    //5 3 7
    one = ilist;  //测试“=”运算符重载
    p = one.removeFront(); //返回并删除one的第一个数据
    cout << "one first number is:" << *p << endl; //结果应为5
    Dlist<int> two(ilist); //测试拷贝构造函数
    p = two.removeFront(); //返回并删除two的第一个数据
    cout << "two first number is:" << *p << endl; //结果应为5
    ip = ilist.removeFront(); //返回并删除ilist的第一个数据
    cout << "ilist first number is:" << *ip << endl; //结果应为5
    j = ilist.removeBack(); //测试从末尾删除元素,返回并删除ilist的最后一个数据
    cout << "ilist last number is:" << *j << endl; //结果应为7
    delete ip;
    delete j;
    delete i;
    delete p;
    return 0;
}

运行结果:
在这里插入图片描述
结果解释:

 程序先依次从ilist表头中插入3,5,然后从表尾插入7,则表中数据依次5,3,7.
 one表是用来测试“=”运算符重载函数的,让one=ilist,取其头元素的值。第一行值
 为5,说明正确。
 two表是用来测试拷贝构造函数的,取其表头的值,第二行值为5,说明拷贝构造函数正确。
 第三行是测试从表头返回并删除元素,值为5,说明正确。
 第四行是测试从表尾返回并删除元素,值为7,说明正确。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

格格不入ち

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值