您的位置:首页 > 其它

练习 -- 使用双向链表来实现双向队列

2016-12-21 14:09 429 查看
1.题目:

使用一个双向链表来实现一个双向的队列,并且让队列具有以下的操作:

(1)判断队列是否为空

(2)得到双向队列中元素的个数

(3)向左端添加一个新元素

(4)向右端添加一个新元素

(5)从左端删除一个元素

(6)从右端删除一个元素

2.分析:

有了双向链表,我们就可以创建我们自己的双向队列,并且很容易地就能实现上面的操作

3.代码:

doublelist.hpp

#ifndef DOUBLELIST_HPP
#define DOUBLELIST_HPP

template<typename T>
class DoubleList
{
public:
DoubleList();
~DoubleList();
void insertAtHead(T item);  	//在表头插入节点
void insertAtTail(T item);		//在表尾插入节点
T deleteAtHead();				//在表头删除节点
T deleteAtTail();				//在表尾删除节点
bool isEmpty();					//判空
int size();						//得到元素的个数
private:
class Node            //内部节点类
{
public:
Node(T item) : next(nullptr), pre(nullptr), data(item){}
~Node(){}
T data;
Node* next;
Node* pre;
};
Node* first;
Node* tail;
int sizeOfList;
};

template<typename T>
DoubleList<T>::DoubleList() : first(nullptr), tail(nullptr), sizeOfList(0) {}

template<typename T>
DoubleList<T>::~DoubleList()
{
if (isEmpty())
{

}
else
{
while (first != nullptr)
{
Node* deleteNode = first;
first = first->next;
deleteNode->next = nullptr;
delete deleteNode;
}
}
}

template<typename T>
void DoubleList<T>::insertAtHead(T item)
{
if (isEmpty())           //如果表为空
{
Node* currentNode = new Node(item);
first = tail = currentNode;
}
else
{
Node* currentNode = new Node(item);
currentNode->next = first;
first->pre = currentNode;
first = currentNode;
}
sizeOfList++;
}

template<typename T>
void DoubleList<T>::insertAtTail(T item)
{
if (isEmpty())        // 如果表为空
{
Node* currentNode = new Node(item);
first = tail = currentNode;
}
else
{
Node* currentNode = new Node(item);
currentNode->pre = tail;
tail->next = currentNode;
tail = currentNode;
}
sizeOfList++;
}

template<typename T>
T DoubleList<T>::deleteAtHead()
{
if (isEmpty())        // 如果表为空
{
return nullptr;
}
else
{
T returnData = first->data;
Node* deleteNode = first;
first = first->next;
deleteNode->next = nullptr;
delete deleteNode;
sizeOfList--;
return returnData;
}

return nullptr;
}

//模版特化
template<>
int DoubleList<int>::deleteAtHead()
{
if (isEmpty())        // 如果表为空
{
return 0;
}
else
{
int returnData = first->data;
Node* deleteNode = first;
first = first->next;
deleteNode->next = nullptr;
delete deleteNode;
sizeOfList--;
return returnData;
}

return 0;
}

template<typename T>
T DoubleList<T>::deleteAtTail()
{
if (isEmpty())        // 如果表为空
{
return nullptr;
}
else
{
int returnData = tail->data;
Node* deleteNode = tail;
tail = tail->pre;
deleteNode->pre = nullptr;
delete deleteNode;
sizeOfList--;
return returnData;
}

return nullptr;
}

//模版特化
template<>
int DoubleList<int>::deleteAtTail()
{
if (isEmpty())        // 如果表为空
{
return 0;
}
else
{
int returnData = tail->data;
Node* deleteNode = tail;
tail = tail->pre;
deleteNode->pre = nullptr;
delete deleteNode;
sizeOfList--;
return returnData;
}

return 0;
}

template<typename T>
bool DoubleList<T>::isEmpty()
{
return sizeOfList == 0;
}

template<typename T>
int DoubleList<T>::size()
{
return sizeOfList;
}

#endif

deque.hpp

#ifndef DEQUE_HPP
#define DEQUE_HPP

#include "doublelist.hpp"

template<typename T>
class Deque
{
public:
Deque();					//创建空的双向队列
~Deque();
void pushLeft(T item);    //向左端添加一个新元素
void pushRight(T item);   //向右端添加一个新元素
T popLeft();			  //从左端删除一个元素
T popRight();			  //从右端删除一个元素
int size();				  //双向队列中的元素数量
bool isEmpty();			  //双向队列是否为空
private:
DoubleList<T> myList;
};

template<typename T>
Deque<T>::Deque() : myList(){}

template<typename T>
Deque<T>::~Deque()
{

}

template<typename T>
int Deque<T>::size()
{
return myList.size();
}

template<typename T>
void Deque<T>::pushLeft(T item)
{
myList.insertAtHead(item);
}

template<typename T>
void Deque<T>::pushRight(T item)
{
myList.insertAtTail(item);
}

template<typename T>
T Deque<T>::popLeft()
{
return myList.deleteAtHead();
}

template<typename T>
T Deque<T>::popRight()
{
return myList.deleteAtTail();
}

template<typename T>
bool Deque<T>::isEmpty()
{
return myList.isEmpty();
}

#endif

main.cpp

#include <iostream>
#include <string>
#include "deque.hpp"

using namespace std;

int main(int agrc, char** argv)
{
Deque<int> deque;
for(int i = 0; i != 5; ++i)
{
deque.pushLeft(i);
}

for (int i = 5; i != 0; --i)
{
deque.pushRight(i);
}

int size = deque.size();
for (int i = 0; i != size; ++i)
{
//cout << deque.popLeft() << " ";
cout << deque.popRight() << " ";
}
cout << endl;

return 0;
}


4.总结:双向队列还能使用动态数组来实现,但是使用数组的话,在左端插入元素的操作所需的时间跟集合大小相关,会花费多余的时间,所以我们还是使用双向链表来实现双向队列。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: