数据结构基础(14) --链式队列的设计与实现
2015-01-10 20:37
756 查看
链式队列是基于单链表的一种存储表示, 其形状如下图所示:
(队列的队头指针指向单链表的第一个结点, 队尾指针指向单链表的最后一个结点, 注意没有无用的空[头/尾]节点)
用单链表表示的链式队列特别适合于数据元素变动比较大的情况, 而且不存在队列满而产生溢出的情况;
链式队列结点构造:
[这次我们将节点构造成了类LinkQueue的嵌套类]
struct ChainNode
{
ChainNode(const Type &_data, ChainNode *_next = NULL)
:data(_data), next(_next) {}
Type data;
ChainNode *next;
};
链式队列构造:template <typename Type>
class LinkQueue
{
template <typename T>
friend ostream &operator<<(ostream &os, LinkQueue<T> &queue);
public:
LinkQueue();
~LinkQueue();
bool isEmpty() const;
void push(const Type &data);
void pop();
//返回队首元素
const Type &front() const;
//返回队尾元素
const Type &back() const;
//清空队列
void makeEmpty();
private:
struct ChainNode
{
ChainNode(const Type &_data, ChainNode *_next = NULL)
:data(_data), next(_next) {}
Type data;
ChainNode *next;
};
private:
ChainNode *m_front; //队首指针[注意不是指向一个无用的空节点]
ChainNode *m_back; //队尾指针[注意不是指向一个无用的空节点]
};
队列的构造与析构:template <typename Type>
LinkQueue<Type>::LinkQueue()
{
m_front = m_back = NULL;
}
template <typename Type>
LinkQueue<Type>::~LinkQueue()
{
makeEmpty();
}
队列的四大操作://入队, 这是链式队列的关键
template <typename Type>
void LinkQueue<Type>::push(const Type &data)
{
if (isEmpty())
{
//如果队列为空
//则队首与队尾指针共同指向一个新构造的对象
m_front = m_back = new ChainNode(data);
}
else
{
//首先让队尾的下一位置指向一个新构造的对象
m_back->next = new ChainNode(data);
//然后队尾指针后移
m_back = m_back->next;
}
}
清空队列与判空操作:template <typename Type>
void LinkQueue<Type>::makeEmpty()
{
while (!isEmpty())
{
pop();
}
}
输出队列所有元素(以做测试):template <typename Type>
ostream &operator<<(ostream &os, LinkQueue<Type> &queue)
{
for (typename LinkQueue<Type>::ChainNode *currentNode = queue.m_front;
currentNode != NULL;
currentNode = currentNode->next)
{
os << currentNode->data << ' ';
}
return os;
}
附-测试代码:int main()
{
LinkQueue<int> queue;
for (int i = 0; i < 10; ++i)
{
queue.push(rand()%100);
}
cout << queue << endl;
cout << queue.front() << endl;
queue.pop();
cout << queue.front() << endl;
cout << queue.back() << endl;
cout << queue << endl;
LinkQueue<char> cQueue;
cQueue.push('A');
cout << "cQueue.front = " << cQueue.front() << endl;
cout << "cQueue.back = " << cQueue.back() << endl;
cQueue.pop();
cout << cQueue << endl;
try
{
cout << "cQueue.front = " << cQueue.front() << endl;
cout << "cQueue.back = " << cQueue.back() << endl;
}
catch(const std::exception &e)
{
cerr << e.what() << endl;
}
return 0;
}
(队列的队头指针指向单链表的第一个结点, 队尾指针指向单链表的最后一个结点, 注意没有无用的空[头/尾]节点)
用单链表表示的链式队列特别适合于数据元素变动比较大的情况, 而且不存在队列满而产生溢出的情况;
链式队列结点构造:
[这次我们将节点构造成了类LinkQueue的嵌套类]
struct ChainNode
{
ChainNode(const Type &_data, ChainNode *_next = NULL)
:data(_data), next(_next) {}
Type data;
ChainNode *next;
};
链式队列构造:template <typename Type>
class LinkQueue
{
template <typename T>
friend ostream &operator<<(ostream &os, LinkQueue<T> &queue);
public:
LinkQueue();
~LinkQueue();
bool isEmpty() const;
void push(const Type &data);
void pop();
//返回队首元素
const Type &front() const;
//返回队尾元素
const Type &back() const;
//清空队列
void makeEmpty();
private:
struct ChainNode
{
ChainNode(const Type &_data, ChainNode *_next = NULL)
:data(_data), next(_next) {}
Type data;
ChainNode *next;
};
private:
ChainNode *m_front; //队首指针[注意不是指向一个无用的空节点]
ChainNode *m_back; //队尾指针[注意不是指向一个无用的空节点]
};
队列的构造与析构:template <typename Type>
LinkQueue<Type>::LinkQueue()
{
m_front = m_back = NULL;
}
template <typename Type>
LinkQueue<Type>::~LinkQueue()
{
makeEmpty();
}
队列的四大操作://入队, 这是链式队列的关键
template <typename Type>
void LinkQueue<Type>::push(const Type &data)
{
if (isEmpty())
{
//如果队列为空
//则队首与队尾指针共同指向一个新构造的对象
m_front = m_back = new ChainNode(data);
}
else
{
//首先让队尾的下一位置指向一个新构造的对象
m_back->next = new ChainNode(data);
//然后队尾指针后移
m_back = m_back->next;
}
}
//出队 template <typename Type> void LinkQueue<Type>::pop() { if (isEmpty()) throw std::range_error("queue is empty"); ChainNode *deleteNode = m_front; // 队首指针后移 m_front = m_front->next; delete deleteNode; }
//取队首元素 template <typename Type> const Type &LinkQueue<Type>::front() const { if (isEmpty()) throw std::range_error("queue is empty"); return (m_front->data); }
//取队尾元素 template <typename Type> const Type &LinkQueue<Type>::back() const { if (isEmpty()) throw std::range_error("queue is empty"); return (m_back->data); }
清空队列与判空操作:template <typename Type>
void LinkQueue<Type>::makeEmpty()
{
while (!isEmpty())
{
pop();
}
}
template <typename Type> bool LinkQueue<Type>::isEmpty() const { return (m_front == NULL); }
输出队列所有元素(以做测试):template <typename Type>
ostream &operator<<(ostream &os, LinkQueue<Type> &queue)
{
for (typename LinkQueue<Type>::ChainNode *currentNode = queue.m_front;
currentNode != NULL;
currentNode = currentNode->next)
{
os << currentNode->data << ' ';
}
return os;
}
附-测试代码:int main()
{
LinkQueue<int> queue;
for (int i = 0; i < 10; ++i)
{
queue.push(rand()%100);
}
cout << queue << endl;
cout << queue.front() << endl;
queue.pop();
cout << queue.front() << endl;
cout << queue.back() << endl;
cout << queue << endl;
LinkQueue<char> cQueue;
cQueue.push('A');
cout << "cQueue.front = " << cQueue.front() << endl;
cout << "cQueue.back = " << cQueue.back() << endl;
cQueue.pop();
cout << cQueue << endl;
try
{
cout << "cQueue.front = " << cQueue.front() << endl;
cout << "cQueue.back = " << cQueue.back() << endl;
}
catch(const std::exception &e)
{
cerr << e.what() << endl;
}
return 0;
}
相关文章推荐
- 数据结构基础(14) --链式队列的设计与实现
- 数据结构基础(14) --链式队列的设计与实现
- 数据结构基础(14) --链式队列的设计与实现
- 数据结构基础(7) --循环队列的设计与实现
- 数据结构基础(7) --循环队列的设计与实现
- 数据结构基础(7) --循环队列的设计与实现
- 数据结构基础(7) --循环队列的设计与实现
- 数据结构基础(7) --循环队列的设计与实现
- 数据结构之数组实现基础队列结构
- 数据结构基础(6) --顺序栈的设计与实现
- 数据结构——队列的链式实现(C语言)
- C# 数据结构基础-实现循环队列
- 数据结构基础(12) --双向循环链表的设计与实现
- 数据结构基础(10) --单链表迭代器的设计与实现
- 数据结构基础(11) --循环链表的设计与实现
- 数据结构基础(11) --循环链表的设计与实现
- 数据结构基础(9) --单链表的设计与实现(2)之高级操作
- 数据结构基础(12) --双向循环链表的设计与实现
- 程序员面试宝典之数据结构基础----C++两个栈实现一个队列功能
- 数据结构基础(8) --单链表的设计与实现(1)之基本操作